OSDN Git Service

add translation
[jnethack/source.git] / src / hack.c
1 /* NetHack 3.6  hack.c  $NHDT-Date: 1551137618 2019/02/25 23:33:38 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.208 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Derek S. Ray, 2015. */
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-2019            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 /* #define DEBUG */ /* uncomment for debugging */
14
15 STATIC_DCL void NDECL(maybe_wail);
16 STATIC_DCL int NDECL(moverock);
17 STATIC_DCL int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
18 STATIC_DCL void NDECL(dosinkfall);
19 STATIC_DCL boolean FDECL(findtravelpath, (int));
20 STATIC_DCL boolean FDECL(trapmove, (int, int, struct trap *));
21 STATIC_DCL struct monst *FDECL(monstinroom, (struct permonst *, int));
22 STATIC_DCL boolean FDECL(doorless_door, (int, int));
23 STATIC_DCL void FDECL(move_update, (BOOLEAN_P));
24 STATIC_DCL void FDECL(maybe_smudge_engr, (int, int, int, int));
25 STATIC_DCL void NDECL(domove_core);
26
27 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
28
29 /* mode values for findtravelpath() */
30 #define TRAVP_TRAVEL 0
31 #define TRAVP_GUESS  1
32 #define TRAVP_VALID  2
33
34 static anything tmp_anything;
35
36 anything *
37 uint_to_any(ui)
38 unsigned ui;
39 {
40     tmp_anything = zeroany;
41     tmp_anything.a_uint = ui;
42     return &tmp_anything;
43 }
44
45 anything *
46 long_to_any(lng)
47 long lng;
48 {
49     tmp_anything = zeroany;
50     tmp_anything.a_long = lng;
51     return &tmp_anything;
52 }
53
54 anything *
55 monst_to_any(mtmp)
56 struct monst *mtmp;
57 {
58     tmp_anything = zeroany;
59     tmp_anything.a_monst = mtmp;
60     return &tmp_anything;
61 }
62
63 anything *
64 obj_to_any(obj)
65 struct obj *obj;
66 {
67     tmp_anything = zeroany;
68     tmp_anything.a_obj = obj;
69     return &tmp_anything;
70 }
71
72 boolean
73 revive_nasty(x, y, msg)
74 int x, y;
75 const char *msg;
76 {
77     register struct obj *otmp, *otmp2;
78     struct monst *mtmp;
79     coord cc;
80     boolean revived = FALSE;
81
82     for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
83         otmp2 = otmp->nexthere;
84         if (otmp->otyp == CORPSE
85             && (is_rider(&mons[otmp->corpsenm])
86                 || otmp->corpsenm == PM_WIZARD_OF_YENDOR)) {
87             /* move any living monster already at that location */
88             if ((mtmp = m_at(x, y)) && enexto(&cc, x, y, mtmp->data))
89                 rloc_to(mtmp, cc.x, cc.y);
90             if (msg)
91                 Norep("%s", msg);
92             revived = revive_corpse(otmp);
93         }
94     }
95
96     /* this location might not be safe, if not, move revived monster */
97     if (revived) {
98         mtmp = m_at(x, y);
99         if (mtmp && !goodpos(x, y, mtmp, 0)
100             && enexto(&cc, x, y, mtmp->data)) {
101             rloc_to(mtmp, cc.x, cc.y);
102         }
103         /* else impossible? */
104     }
105
106     return revived;
107 }
108
109 STATIC_OVL int
110 moverock()
111 {
112     register xchar rx, ry, sx, sy;
113     register struct obj *otmp;
114     register struct trap *ttmp;
115     register struct monst *mtmp;
116
117     sx = u.ux + u.dx, sy = u.uy + u.dy; /* boulder starting position */
118     while ((otmp = sobj_at(BOULDER, sx, sy)) != 0) {
119         /* make sure that this boulder is visible as the top object */
120         if (otmp != level.objects[sx][sy])
121             movobj(otmp, sx, sy);
122
123         rx = u.ux + 2 * u.dx; /* boulder destination position */
124         ry = u.uy + 2 * u.dy;
125         nomul(0);
126         if (Levitation || Is_airlevel(&u.uz)) {
127             if (Blind)
128                 feel_location(sx, sy);
129 /*JP
130             You("don't have enough leverage to push %s.", the(xname(otmp)));
131 */
132             You("\91Ì\82ª\95\82\82¢\82Ä\82¢\82é\82Ì\82Å%s\82ð\89\9f\82¹\82È\82¢\81D", the(xname(otmp)));
133             /* Give them a chance to climb over it? */
134             return -1;
135         }
136         if (verysmall(youmonst.data) && !u.usteed) {
137             if (Blind)
138                 feel_location(sx, sy);
139 /*JP
140             pline("You're too small to push that %s.", xname(otmp));
141 */
142             You("\8f¬\82³\82·\82¬\82Ä%s\82ð\89\9f\82¹\82È\82¢\81D",xname(otmp));
143             goto cannot_push;
144         }
145         if (isok(rx, ry) && !IS_ROCK(levl[rx][ry].typ)
146             && levl[rx][ry].typ != IRONBARS
147             && (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy)
148                 || doorless_door(rx, ry)) && !sobj_at(BOULDER, rx, ry)) {
149             ttmp = t_at(rx, ry);
150             mtmp = m_at(rx, ry);
151
152             /* KMH -- Sokoban doesn't let you push boulders diagonally */
153             if (Sokoban && u.dx && u.dy) {
154                 if (Blind)
155                     feel_location(sx, sy);
156 /*JP
157                 pline("%s won't roll diagonally on this %s.",
158 */
159                 pline("%s\82Ì\8fã\82Å\82Í%s\82Í\8eÎ\82ß\82É\89\9f\82¹\82È\82¢\81D",
160                       The(xname(otmp)), surface(sx, sy));
161                 goto cannot_push;
162             }
163
164 /*JP
165             if (revive_nasty(rx, ry, "You sense movement on the other side."))
166 */
167             if (revive_nasty(rx, ry, "\94½\91Î\91¤\82É\93®\82«\82ð\8a´\82\82½\81D"))
168                 return -1;
169
170             if (mtmp && !noncorporeal(mtmp->data)
171                 && (!mtmp->mtrapped
172                     || !(ttmp && is_pit(ttmp->ttyp)))) {
173                 if (Blind)
174                     feel_location(sx, sy);
175                 if (canspotmon(mtmp)) {
176 /*JP
177                     pline("There's %s on the other side.", a_monnam(mtmp));
178 */
179                     pline("\94½\91Î\91¤\82É%s\82ª\82¢\82é\81D", a_monnam(mtmp));
180                 } else {
181 /*JP
182                     You_hear("a monster behind %s.", the(xname(otmp)));
183 */
184                     pline("%s\82Ì\94w\8cã\82É\89ö\95¨\82Ì\8bC\94z\82ª\82·\82é\81D", the(xname(otmp)));
185                     map_invisible(rx, ry);
186                 }
187                 if (flags.verbose)
188 #if 0 /*JP*/
189                     pline("Perhaps that's why %s cannot move it.",
190                           u.usteed ? y_monnam(u.usteed) : "you");
191 #else
192                     pline("\82½\82Ô\82ñ\82±\82ê\82ª\81C\8aâ\82ð\93®\82©\82¹\82È\82¢\97\9d\97R\82¾\81D");
193 #endif
194                 goto cannot_push;
195             }
196
197             if (ttmp) {
198                 /* if a trap operates on the boulder, don't attempt
199                    to move any others at this location; return -1
200                    if another boulder is in hero's way, or 0 if he
201                    should advance to the vacated boulder position */
202                 switch (ttmp->ttyp) {
203                 case LANDMINE:
204                     if (rn2(10)) {
205                         obj_extract_self(otmp);
206                         place_object(otmp, rx, ry);
207                         newsym(sx, sy);
208 #if 0 /*JP*/
209                         pline("KAABLAMM!!!  %s %s land mine.",
210                               Tobjnam(otmp, "trigger"),
211                               ttmp->madeby_u ? "your" : "a");
212 #else
213                         pline("\82¿\82ã\82Ç\81[\82ñ\81I\81I%s\82Å%s\92n\97\8b\82Ì\8bN\94\9a\83X\83C\83b\83`\82ª\93ü\82Á\82½\81D",
214                               xname(otmp),
215                               ttmp->madeby_u ? "\82 \82È\82½\82Ì\8ed\8a|\82¯\82½" : "");
216 #endif
217                         blow_up_landmine(ttmp);
218                         /* if the boulder remains, it should fill the pit */
219                         fill_pit(u.ux, u.uy);
220                         if (cansee(rx, ry))
221                             newsym(rx, ry);
222                         return sobj_at(BOULDER, sx, sy) ? -1 : 0;
223                     }
224                     break;
225                 case SPIKED_PIT:
226                 case PIT:
227                     obj_extract_self(otmp);
228                     /* vision kludge to get messages right;
229                        the pit will temporarily be seen even
230                        if this is one among multiple boulders */
231                     if (!Blind)
232                         viz_array[ry][rx] |= IN_SIGHT;
233 /*JP
234                     if (!flooreffects(otmp, rx, ry, "fall")) {
235 */
236                     if (!flooreffects(otmp, rx, ry, "\97\8e\82¿\82é")) {
237                         place_object(otmp, rx, ry);
238                     }
239                     if (mtmp && !Blind)
240                         newsym(rx, ry);
241                     return sobj_at(BOULDER, sx, sy) ? -1 : 0;
242                 case HOLE:
243                 case TRAPDOOR:
244                     if (Blind)
245 /*JP
246                         pline("Kerplunk!  You no longer feel %s.",
247 */
248                         pline("\83h\83T\83b\81I\82 \82È\82½\82Í\82à\82¤%s\82ð\8a´\82\82ç\82ê\82È\82¢\81D",
249                               the(xname(otmp)));
250                     else
251 #if 0 /*JP*/
252                         pline("%s%s and %s a %s in the %s!",
253                               Tobjnam(otmp, (ttmp->ttyp == TRAPDOOR)
254                                                 ? "trigger"
255                                                 : "fall"),
256                               (ttmp->ttyp == TRAPDOOR) ? "" : " into",
257                               otense(otmp, "plug"),
258                               (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole",
259                               surface(rx, ry));
260 #else
261                         pline("%s\82Í\97\8e\82¿\82Ä%s\82Ì%s\82ð\96\84\82ß\82½\81I",
262                               xname(otmp),
263                               surface(rx, ry),
264                               (ttmp->ttyp == TRAPDOOR) ? "\97\8e\82µ\94à" : "\8c\8a");
265 #endif
266                     deltrap(ttmp);
267                     delobj(otmp);
268                     bury_objs(rx, ry);
269                     levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
270                     levl[rx][ry].candig = 1;
271                     if (cansee(rx, ry))
272                         newsym(rx, ry);
273                     return sobj_at(BOULDER, sx, sy) ? -1 : 0;
274                 case LEVEL_TELEP:
275                 case TELEP_TRAP: {
276                     int newlev = 0; /* lint suppression */
277                     d_level dest;
278
279                     if (ttmp->ttyp == LEVEL_TELEP) {
280                         newlev = random_teleport_level();
281                         if (newlev == depth(&u.uz) || In_endgame(&u.uz))
282                             /* trap didn't work; skip "disappears" message */
283                             goto dopush;
284                     }
285                     if (u.usteed)
286 /*JP
287                         pline("%s pushes %s and suddenly it disappears!",
288 */
289                         pline("%s\82ª%s\82ð\89\9f\82·\82Æ\81C\93Ë\91R\82»\82ê\82Í\8fÁ\96Å\82µ\82½\81I",
290                               upstart(y_monnam(u.usteed)), the(xname(otmp)));
291                     else
292 /*JP
293                         You("push %s and suddenly it disappears!",
294 */
295                         pline("\82 \82È\82½\82ª%s\82ð\89\9f\82·\82Æ\81C\93Ë\91R\82»\82ê\82Í\8fÁ\96Å\82µ\82½\81I",
296                             the(xname(otmp)));
297                     if (ttmp->ttyp == TELEP_TRAP) {
298                         (void) rloco(otmp);
299                     } else {
300                         obj_extract_self(otmp);
301                         add_to_migration(otmp);
302                         get_level(&dest, newlev);
303                         otmp->ox = dest.dnum;
304                         otmp->oy = dest.dlevel;
305                         otmp->owornmask = (long) MIGR_RANDOM;
306                     }
307                     seetrap(ttmp);
308                     return sobj_at(BOULDER, sx, sy) ? -1 : 0;
309                 }
310                 default:
311                     break; /* boulder not affected by this trap */
312                 }
313             }
314
315             if (closed_door(rx, ry))
316                 goto nopushmsg;
317             if (boulder_hits_pool(otmp, rx, ry, TRUE))
318                 continue;
319             /*
320              * Re-link at top of fobj chain so that pile order is preserved
321              * when level is restored.
322              */
323             if (otmp != fobj) {
324                 remove_object(otmp);
325                 place_object(otmp, otmp->ox, otmp->oy);
326             }
327
328             {
329 #ifdef LINT /* static long lastmovetime; */
330                 long lastmovetime;
331                 lastmovetime = 0;
332 #else
333                 /* note: reset to zero after save/restore cycle */
334                 static NEARDATA long lastmovetime;
335 #endif
336  dopush:
337                 if (!u.usteed) {
338                     if (moves > lastmovetime + 2 || moves < lastmovetime)
339 #if 0 /*JP*/
340                         pline("With %s effort you move %s.",
341                               throws_rocks(youmonst.data) ? "little"
342                                                           : "great",
343                               the(xname(otmp)));
344 #else
345                         pline("%s\97Í\82ð\82±\82ß\82Ä%s\82ð\89\9f\82µ\82½\81D",
346                               throws_rocks(youmonst.data) ? "\8f­\82µ" : "\82©\82È\82è",
347                               the(xname(otmp)));
348 #endif
349                     exercise(A_STR, TRUE);
350                 } else
351 #if 0 /*JP*/
352                     pline("%s moves %s.", upstart(y_monnam(u.usteed)),
353                           the(xname(otmp)));
354 #else
355                     pline("%s\82Í%s\82ð\93®\82©\82µ\82½\81D", upstart(y_monnam(u.usteed)),
356                           xname(otmp));
357 #endif
358                 lastmovetime = moves;
359             }
360
361             /* Move the boulder *after* the message. */
362             if (glyph_is_invisible(levl[rx][ry].glyph))
363                 unmap_object(rx, ry);
364             movobj(otmp, rx, ry); /* does newsym(rx,ry) */
365             if (Blind) {
366                 feel_location(rx, ry);
367                 feel_location(sx, sy);
368             } else {
369                 newsym(sx, sy);
370             }
371         } else {
372  nopushmsg:
373             if (u.usteed)
374 #if 0 /*JP*/
375                 pline("%s tries to move %s, but cannot.",
376                       upstart(y_monnam(u.usteed)), the(xname(otmp)));
377 #else
378                 pline("%s\82Í%s\82ð\93®\82©\82»\82¤\82Æ\82µ\82½\82ª\8fo\97\88\82È\82©\82Á\82½\81D",
379                       upstart(y_monnam(u.usteed)), the(xname(otmp)));
380 #endif
381             else
382 /*JP
383                 You("try to move %s, but in vain.", the(xname(otmp)));
384 */
385                 You("%s\82ð\93®\82©\82»\82¤\82Æ\82µ\82½\82ª\81C\82¾\82ß\82¾\82Á\82½\81D", the(xname(otmp)));
386             if (Blind)
387                 feel_location(sx, sy);
388  cannot_push:
389             if (throws_rocks(youmonst.data)) {
390                 boolean
391                     canpickup = (!Sokoban
392                                  /* similar exception as in can_lift():
393                                     when poly'd into a giant, you can
394                                     pick up a boulder if you have a free
395                                     slot or into the overflow ('#') slot
396                                     unless already carrying at least one */
397                               && (inv_cnt(FALSE) < 52 || !carrying(BOULDER))),
398                     willpickup = (canpickup && autopick_testobj(otmp, TRUE));
399
400                 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
401 #if 0 /*JP*/
402                     You("aren't skilled enough to %s %s from %s.",
403                         willpickup ? "pick up" : "push aside",
404                         the(xname(otmp)), y_monnam(u.usteed));
405 #else
406                     You("%s\82É%s\82ð%s\82é\82Ù\82Ç\8bZ\97Ê\82ª\82È\82¢\81D",
407                         y_monnam(u.usteed), the(xname(otmp)), 
408                         willpickup ? "\8fE\82í\82¹" : "\89\9f\82³\82¹");
409 #endif
410                 } else {
411                     /*
412                      * willpickup:  you easily pick it up
413                      * canpickup:   you could easily pick it up
414                      * otherwise:   you easily push it aside
415                      */
416 #if 0 /*JP*/
417                     pline("However, you %seasily %s.",
418                           (willpickup || !canpickup) ? "" : "could ",
419                           (willpickup || canpickup) ? "pick it up"
420                                                     : "push it aside");
421 #else
422                     pline("\82µ\82©\82µ\81C\82 \82È\82½\82Í\8aÈ\92P\82É\82»\82ê\82ð%s\81D",
423                           (willpickup || canpickup) ?
424                           "\8fE\82¦\82½" : "\95Ê\82Ì\95û\82É\89\9f\82¹\82½");
425 #endif
426                     sokoban_guilt();
427                     break;
428                 }
429                 break;
430             }
431
432             if (!u.usteed
433                 && (((!invent || inv_weight() <= -850)
434                      && (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][sy].typ)
435                                             && IS_ROCK(levl[sx][u.uy].typ))))
436                     || verysmall(youmonst.data))) {
437                 pline(
438 /*JP
439                    "However, you can squeeze yourself into a small opening.");
440 */
441                     "\82µ\82©\82µ\81C\82 \82È\82½\82Í\8f¬\82³\82¢\8c\84\8aÔ\82É\82±\82\93ü\82Á\82½\81D");
442                 sokoban_guilt();
443                 break;
444             } else
445                 return -1;
446         }
447     }
448     return 0;
449 }
450
451 /*
452  *  still_chewing()
453  *
454  *  Chew on a wall, door, or boulder.  [What about statues?]
455  *  Returns TRUE if still eating, FALSE when done.
456  */
457 STATIC_OVL int
458 still_chewing(x, y)
459 xchar x, y;
460 {
461     struct rm *lev = &levl[x][y];
462     struct obj *boulder = sobj_at(BOULDER, x, y);
463     const char *digtxt = (char *) 0, *dmgtxt = (char *) 0;
464
465     if (context.digging.down) /* not continuing previous dig (w/ pick-axe) */
466         (void) memset((genericptr_t) &context.digging, 0,
467                       sizeof (struct dig_info));
468
469     if (!boulder
470         && ((IS_ROCK(lev->typ) && !may_dig(x, y))
471             /* may_dig() checks W_NONDIGGABLE but doesn't handle iron bars */
472             || (lev->typ == IRONBARS && (lev->wall_info & W_NONDIGGABLE)))) {
473 #if 0 /*JP*/
474         You("hurt your teeth on the %s.",
475             (lev->typ == IRONBARS)
476                 ? "bars"
477                 : IS_TREE(lev->typ)
478                     ? "tree"
479                     : "hard stone");
480 #else
481         You("%s\82Å\8e\95\82ð\92É\82ß\82½\81D",
482             (lev->typ == IRONBARS)
483                 ? "\93S\82Ì\96_"
484                 : IS_TREE(lev->typ)
485                     ? "\96Ø"
486                     : "\8cÅ\82¢\8aâ");
487 #endif
488         nomul(0);
489         return 1;
490     } else if (context.digging.pos.x != x || context.digging.pos.y != y
491                || !on_level(&context.digging.level, &u.uz)) {
492         context.digging.down = FALSE;
493         context.digging.chew = TRUE;
494         context.digging.warned = FALSE;
495         context.digging.pos.x = x;
496         context.digging.pos.y = y;
497         assign_level(&context.digging.level, &u.uz);
498         /* solid rock takes more work & time to dig through */
499         context.digging.effort =
500             (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc;
501 #if 0 /*JP*/
502         You("start chewing %s %s.",
503             (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS)
504                 ? "on a"
505                 : "a hole in the",
506             boulder
507                 ? "boulder"
508                 : IS_TREE(lev->typ)
509                     ? "tree"
510                     : IS_ROCK(lev->typ)
511                         ? "rock"
512                         : (lev->typ == IRONBARS)
513                             ? "bar"
514                             : "door");
515 #else
516         You("%s%s\82Í\82\82ß\82½\81D",
517             boulder
518             ? "\8aâ"
519             : IS_TREE(lev->typ)
520               ? "\96Ø"
521               : IS_ROCK(lev->typ)
522                 ? "\90Î"
523                 : lev->typ == IRONBARS
524                   ? "\93S\82Ì\96_"
525                   : "\94à",
526             (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS)
527               ? "\82ð\8a\9a\82Ý"
528               : "\82É\8c\8a\82ð\82 \82¯");
529 #endif
530         watch_dig((struct monst *) 0, x, y, FALSE);
531         return 1;
532     } else if ((context.digging.effort += (30 + u.udaminc)) <= 100) {
533         if (flags.verbose)
534 #if 0 /*JP*/
535             You("%s chewing on the %s.",
536                 context.digging.chew ? "continue" : "begin",
537                 boulder
538                     ? "boulder"
539                     : IS_TREE(lev->typ)
540                         ? "tree"
541                         : IS_ROCK(lev->typ)
542                             ? "rock"
543                             : (lev->typ == IRONBARS)
544                                 ? "bars"
545                                 : "door");
546 #else
547             You("%s\82ð\8a\9a\82Ý%s\81D",
548                 boulder
549                 ? "\8aâ"
550                 : IS_TREE(lev->typ)
551                   ? "\96Ø"
552                   : IS_ROCK(lev->typ)
553                     ? "\90Î"
554                     : lev->typ == IRONBARS
555                       ? "\93S\82Ì\96_"
556                       : "\94à",
557                 context.digging.chew ? "\91±\82¯\82½" : "\82Í\82\82ß\82½");
558 #endif
559         context.digging.chew = TRUE;
560         watch_dig((struct monst *) 0, x, y, FALSE);
561         return 1;
562     }
563
564     /* Okay, you've chewed through something */
565     u.uconduct.food++;
566     u.uhunger += rnd(20);
567
568     if (boulder) {
569         delobj(boulder);         /* boulder goes bye-bye */
570 #if 0 /*JP*/
571         You("eat the boulder."); /* yum */
572 #else
573         You("\8aâ\82ð\90H\82×\82½\81D"); /* yum */
574 #endif
575
576         /*
577          *  The location could still block because of
578          *      1. More than one boulder
579          *      2. Boulder stuck in a wall/stone/door.
580          *
581          *  [perhaps use does_block() below (from vision.c)]
582          */
583         if (IS_ROCK(lev->typ) || closed_door(x, y)
584             || sobj_at(BOULDER, x, y)) {
585             block_point(x, y); /* delobj will unblock the point */
586             /* reset dig state */
587             (void) memset((genericptr_t) &context.digging, 0,
588                           sizeof (struct dig_info));
589             return 1;
590         }
591
592     } else if (IS_WALL(lev->typ)) {
593         if (*in_rooms(x, y, SHOPBASE)) {
594             add_damage(x, y, SHOP_WALL_DMG);
595 /*JP
596             dmgtxt = "damage";
597 */
598             dmgtxt = "\8f\9d\82Â\82¯\82é";
599         }
600 /*JP
601         digtxt = "chew a hole in the wall.";
602 */
603         digtxt = "\95Ç\82É\8c\8a\82ð\8aJ\82¯\82½\81D";
604         if (level.flags.is_maze_lev) {
605             lev->typ = ROOM;
606         } else if (level.flags.is_cavernous_lev && !in_town(x, y)) {
607             lev->typ = CORR;
608         } else {
609             lev->typ = DOOR;
610             lev->doormask = D_NODOOR;
611         }
612     } else if (IS_TREE(lev->typ)) {
613 /*JP
614         digtxt = "chew through the tree.";
615 */
616         digtxt = "\96Ø\82É\8c\8a\82ð\8aJ\82¯\82½\81D";
617         lev->typ = ROOM;
618     } else if (lev->typ == IRONBARS) {
619 /*JP
620         digtxt = "eat through the bars.";
621 */
622         digtxt = "\93S\82Ì\96_\82É\8c\8a\82ð\8aJ\82¯\82½\81D";
623         dissolve_bars(x, y);
624     } else if (lev->typ == SDOOR) {
625         if (lev->doormask & D_TRAPPED) {
626             lev->doormask = D_NODOOR;
627 /*JP
628             b_trapped("secret door", 0);
629 */
630             b_trapped("\94é\96§\82Ì\94à", 0);
631         } else {
632 /*JP
633             digtxt = "chew through the secret door.";
634 */
635             digtxt = "\94é\96§\82Ì\94à\82ð\8a\9a\82Ý\8dÓ\82¢\82½\81D";
636             lev->doormask = D_BROKEN;
637         }
638         lev->typ = DOOR;
639
640     } else if (IS_DOOR(lev->typ)) {
641         if (*in_rooms(x, y, SHOPBASE)) {
642             add_damage(x, y, SHOP_DOOR_COST);
643 /*JP
644             dmgtxt = "break";
645 */
646             dmgtxt = "\89ó\82·";
647         }
648         if (lev->doormask & D_TRAPPED) {
649             lev->doormask = D_NODOOR;
650 /*JP
651             b_trapped("door", 0);
652 */
653             b_trapped("\94à", 0);
654         } else {
655 /*JP
656             digtxt = "chew through the door.";
657 */
658             digtxt = "\94à\82ð\8dÓ\82¢\82½\81D";
659             lev->doormask = D_BROKEN;
660         }
661
662     } else { /* STONE or SCORR */
663 /*JP
664         digtxt = "chew a passage through the rock.";
665 */
666         digtxt = "\8aâ\82ð\8a\9a\82Ý\8dÓ\82¢\82Ä\92Ê\82è\94²\82¯\82½\81D";
667         lev->typ = CORR;
668     }
669
670     unblock_point(x, y); /* vision */
671     newsym(x, y);
672     if (digtxt)
673         You1(digtxt); /* after newsym */
674     if (dmgtxt)
675         pay_for_damage(dmgtxt, FALSE);
676     (void) memset((genericptr_t) &context.digging, 0,
677                   sizeof (struct dig_info));
678     return 0;
679 }
680
681 void
682 movobj(obj, ox, oy)
683 register struct obj *obj;
684 register xchar ox, oy;
685 {
686     /* optimize by leaving on the fobj chain? */
687     remove_object(obj);
688     newsym(obj->ox, obj->oy);
689     place_object(obj, ox, oy);
690     newsym(ox, oy);
691 }
692
693 /*JP
694 static NEARDATA const char fell_on_sink[] = "fell onto a sink";
695 */
696 static NEARDATA const char fell_on_sink[] = "\97¬\82µ\91ä\82É\97\8e\82¿\82Ä";
697
698 STATIC_OVL void
699 dosinkfall()
700 {
701     register struct obj *obj;
702     int dmg;
703     boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS),
704             innate_lev = ((HLevitation & (FROMOUTSIDE | FROMFORM)) != 0L),
705             /* to handle being chained to buried iron ball, trying to
706                levitate but being blocked, then moving onto adjacent sink;
707                no need to worry about being blocked by terrain because we
708                couldn't be over a sink at the same time */
709             blockd_lev = (BLevitation == I_SPECIAL),
710             ufall = (!innate_lev && !blockd_lev
711                      && !(HFlying || EFlying)); /* BFlying */
712
713     if (!ufall) {
714 /*JP
715         You((innate_lev || blockd_lev) ? "wobble unsteadily for a moment."
716 */
717         You((innate_lev || blockd_lev) ? "\82¿\82å\82Á\82Æ\82Ó\82ç\82Â\82¢\82½\81D"
718 /*JP
719                        : "gain control of your flight.");
720 */
721                        : "\94ò\8ds\92\86\82Ì\90§\8cä\82ð\8eæ\82è\82à\82Ç\82µ\82½\81D");
722     } else {
723         long save_ELev = ELevitation, save_HLev = HLevitation;
724
725         /* fake removal of levitation in advance so that final
726            disclosure will be right in case this turns out to
727            be fatal; fortunately the fact that rings and boots
728            are really still worn has no effect on bones data */
729         ELevitation = HLevitation = 0L;
730 /*JP
731         You("crash to the floor!");
732 */
733         You("\8f°\82É\92@\82«\82Â\82¯\82ç\82ê\82½\81I");
734         dmg = rn1(8, 25 - (int) ACURR(A_CON));
735 #if 0 /*JP*/
736         losehp(Maybe_Half_Phys(dmg), fell_on_sink, NO_KILLER_PREFIX);
737 #else
738         losehp(Maybe_Half_Phys(dmg), fell_on_sink, KILLED_BY);
739 #endif
740         exercise(A_DEX, FALSE);
741 /*JP
742         selftouch("Falling, you");
743 */
744         selftouch("\97\8e\82¿\82È\82ª\82ç\81C\82 \82È\82½\82Í");
745         for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
746             if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) {
747 /*JP
748                 You("fell on %s.", doname(obj));
749 */
750                 You("%s\82Ì\8fã\82É\97\8e\82¿\82½\81D",doname(obj));
751 #if 0 /*JP*/
752                 losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink,
753                        NO_KILLER_PREFIX);
754 #else
755                 losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink,
756                        KILLED_BY);
757 #endif
758                 exercise(A_CON, FALSE);
759             }
760         ELevitation = save_ELev;
761         HLevitation = save_HLev;
762     }
763
764     /*
765      * Interrupt multi-turn putting on/taking off of armor (in which
766      * case we reached the sink due to being teleported while busy;
767      * in 3.4.3, Boots_on()/Boots_off() [called via (*afternmv)() when
768      * 'multi' reaches 0] triggered a crash if we were donning/doffing
769      * levitation boots [because the Boots_off() below causes 'uarmf'
770      * to be null by the time 'afternmv' gets called]).
771      *
772      * Interrupt donning/doffing if we fall onto the sink, or if the
773      * code below is going to remove levitation boots even when we
774      * haven't fallen (innate floating or flying becoming unblocked).
775      */
776     if (ufall || lev_boots) {
777         (void) stop_donning(lev_boots ? uarmf : (struct obj *) 0);
778         /* recalculate in case uarmf just got set to null */
779         lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS);
780     }
781
782     /* remove worn levitation items */
783     ELevitation &= ~W_ARTI;
784     HLevitation &= ~(I_SPECIAL | TIMEOUT);
785     HLevitation++;
786     if (uleft && uleft->otyp == RIN_LEVITATION) {
787         obj = uleft;
788         Ring_off(obj);
789         off_msg(obj);
790     }
791     if (uright && uright->otyp == RIN_LEVITATION) {
792         obj = uright;
793         Ring_off(obj);
794         off_msg(obj);
795     }
796     if (lev_boots) {
797         obj = uarmf;
798         (void) Boots_off();
799         off_msg(obj);
800     }
801     HLevitation--;
802     /* probably moot; we're either still levitating or went
803        through float_down(), but make sure BFlying is up to date */
804     float_vs_flight();
805 }
806
807 /* intended to be called only on ROCKs or TREEs */
808 boolean
809 may_dig(x, y)
810 register xchar x, y;
811 {
812     struct rm *lev = &levl[x][y];
813
814     return (boolean) !((IS_STWALL(lev->typ) || IS_TREE(lev->typ))
815                        && (lev->wall_info & W_NONDIGGABLE));
816 }
817
818 boolean
819 may_passwall(x, y)
820 register xchar x, y;
821 {
822     return (boolean) !(IS_STWALL(levl[x][y].typ)
823                        && (levl[x][y].wall_info & W_NONPASSWALL));
824 }
825
826 boolean
827 bad_rock(mdat, x, y)
828 struct permonst *mdat;
829 register xchar x, y;
830 {
831     return (boolean) ((Sokoban && sobj_at(BOULDER, x, y))
832                       || (IS_ROCK(levl[x][y].typ)
833                           && (!tunnels(mdat) || needspick(mdat)
834                               || !may_dig(x, y))
835                           && !(passes_walls(mdat) && may_passwall(x, y))));
836 }
837
838 /* caller has already decided that it's a tight diagonal; check whether a
839    monster--who might be the hero--can fit through, and if not then return
840    the reason why:  1: can't fit, 2: possessions won't fit, 3: sokoban
841    returns 0 if we can squeeze through */
842 int
843 cant_squeeze_thru(mon)
844 struct monst *mon;
845 {
846     int amt;
847     struct permonst *ptr = mon->data;
848
849     /* too big? */
850     if (bigmonst(ptr)
851         && !(amorphous(ptr) || is_whirly(ptr) || noncorporeal(ptr)
852              || slithy(ptr) || can_fog(mon)))
853         return 1;
854
855     /* lugging too much junk? */
856     amt = (mon == &youmonst) ? inv_weight() + weight_cap()
857                              : curr_mon_load(mon);
858     if (amt > 600)
859         return 2;
860
861     /* Sokoban restriction applies to hero only */
862     if (mon == &youmonst && Sokoban)
863         return 3;
864
865     /* can squeeze through */
866     return 0;
867 }
868
869 boolean
870 invocation_pos(x, y)
871 xchar x, y;
872 {
873     return (boolean) (Invocation_lev(&u.uz)
874                       && x == inv_pos.x && y == inv_pos.y);
875 }
876
877 /* return TRUE if (dx,dy) is an OK place to move
878  * mode is one of DO_MOVE, TEST_MOVE, TEST_TRAV, or TEST_TRAP
879  */
880 boolean
881 test_move(ux, uy, dx, dy, mode)
882 int ux, uy, dx, dy;
883 int mode;
884 {
885     int x = ux + dx;
886     int y = uy + dy;
887     register struct rm *tmpr = &levl[x][y];
888     register struct rm *ust;
889
890     context.door_opened = FALSE;
891     /*
892      *  Check for physical obstacles.  First, the place we are going.
893      */
894     if (IS_ROCK(tmpr->typ) || tmpr->typ == IRONBARS) {
895         if (Blind && mode == DO_MOVE)
896             feel_location(x, y);
897         if (Passes_walls && may_passwall(x, y)) {
898             ; /* do nothing */
899         } else if (Underwater) {
900             /* note: if water_friction() changes direction due to
901                turbulence, new target destination will always be water,
902                so we won't get here, hence don't need to worry about
903                "there" being somewhere the player isn't sure of */
904             if (mode == DO_MOVE)
905 /*JP
906                 pline("There is an obstacle there.");
907 */
908                 pline("\8fá\8aQ\95¨\82ª\82 \82é\81D");
909             return FALSE;
910         } else if (tmpr->typ == IRONBARS) {
911             if ((dmgtype(youmonst.data, AD_RUST)
912                  || dmgtype(youmonst.data, AD_CORR)) && mode == DO_MOVE
913                 && still_chewing(x, y)) {
914                 return FALSE;
915             }
916             if (!(Passes_walls || passes_bars(youmonst.data))) {
917                 if (mode == DO_MOVE && iflags.mention_walls)
918 /*JP
919                     You("cannot pass through the bars.");
920 */
921                     You("\93S\82Ì\96_\82ð\92Ê\82è\94²\82¯\82ç\82ê\82È\82¢\81D");
922                 return FALSE;
923             }
924         } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
925             /* Eat the rock. */
926             if (mode == DO_MOVE && still_chewing(x, y))
927                 return FALSE;
928         } else if (flags.autodig && !context.run && !context.nopick && uwep
929                    && is_pick(uwep)) {
930             /* MRKR: Automatic digging when wielding the appropriate tool */
931             if (mode == DO_MOVE)
932                 (void) use_pick_axe2(uwep);
933             return FALSE;
934         } else {
935             if (mode == DO_MOVE) {
936                 if (is_db_wall(x, y))
937 /*JP
938                     pline("That drawbridge is up!");
939 */
940                     pline("\92µ\82Ë\8b´\82Í\8fã\82Á\82Ä\82¢\82é\81I");
941                 /* sokoban restriction stays even after puzzle is solved */
942                 else if (Passes_walls && !may_passwall(x, y)
943                          && In_sokoban(&u.uz))
944 /*JP
945                     pline_The("Sokoban walls resist your ability.");
946 */
947                     pline_The("\91q\8cÉ\94Ô\82Ì\95Ç\82Í\82 \82È\82½\82Ì\94\\97Í\82É\92ï\8dR\82µ\82½\81D");
948                 else if (iflags.mention_walls)
949 #if 0 /*JP:T*/
950                     pline("It's %s.",
951                           (IS_WALL(tmpr->typ) || tmpr->typ == SDOOR) ? "a wall"
952                           : IS_TREE(tmpr->typ) ? "a tree"
953                           : "solid stone");
954 #else
955                     pline("\82±\82ê\82Í%s\82¾\81D",
956                           (IS_WALL(tmpr->typ) || tmpr->typ == SDOOR) ? "\95Ç"
957                           : IS_TREE(tmpr->typ) ? "\96Ø"
958                           : "\90Î");
959 #endif
960             }
961             return FALSE;
962         }
963     } else if (IS_DOOR(tmpr->typ)) {
964         if (closed_door(x, y)) {
965             if (Blind && mode == DO_MOVE)
966                 feel_location(x, y);
967             if (Passes_walls) {
968                 ; /* do nothing */
969             } else if (can_ooze(&youmonst)) {
970                 if (mode == DO_MOVE)
971 /*JP
972                     You("ooze under the door.");
973 */
974                     You("\83h\83A\82Ì\89º\82©\82ç\82É\82\82Ý\8fo\82½\81D");
975             } else if (Underwater) {
976                 if (mode == DO_MOVE)
977 /*JP
978                     pline("There is an obstacle there.");
979 */
980                     pline("\8fá\8aQ\95¨\82ª\82 \82é\81D");
981                 return FALSE;
982             } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
983                 /* Eat the door. */
984                 if (mode == DO_MOVE && still_chewing(x, y))
985                     return FALSE;
986             } else {
987                 if (mode == DO_MOVE) {
988                     if (amorphous(youmonst.data))
989                         You(
990 /*JP
991    "try to ooze under the door, but can't squeeze your possessions through.");
992 */
993    "\83h\83A\82Ì\89º\82©\82ç\82É\82\82Ý\8fo\82æ\82¤\82Æ\82µ\82½\81C\82µ\82©\82µ\8e\9d\82¿\95¨\82Í\82»\82¤\82Í\82¢\82©\82È\82¢\81D");
994                     if (flags.autoopen && !context.run && !Confusion
995                         && !Stunned && !Fumbling) {
996                         context.door_opened = context.move =
997                             doopen_indir(x, y);
998                     } else if (x == ux || y == uy) {
999                         if (Blind || Stunned || ACURR(A_DEX) < 10
1000                             || Fumbling) {
1001                             if (u.usteed) {
1002 /*JP
1003                                 You_cant("lead %s through that closed door.",
1004 */
1005                                 You_cant("%s\82É\95Â\82Ü\82Á\82½\94à\82ð\92Ê\89ß\82³\82¹\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D",
1006                                          y_monnam(u.usteed));
1007                             } else {
1008 /*JP
1009                                 pline("Ouch!  You bump into a door.");
1010 */
1011                                 pline("\82¢\82Ä\82Á\81I\93ª\82ð\94à\82É\82Ô\82Â\82¯\82½\81D");
1012                                 exercise(A_DEX, FALSE);
1013                             }
1014                         } else
1015 /*JP
1016                             pline("That door is closed.");
1017 */
1018                             pline("\94à\82Í\95Â\82Ü\82Á\82Ä\82¢\82é\81D");
1019                     }
1020                 } else if (mode == TEST_TRAV || mode == TEST_TRAP)
1021                     goto testdiag;
1022                 return FALSE;
1023             }
1024         } else {
1025  testdiag:
1026             if (dx && dy && !Passes_walls
1027                 && (!doorless_door(x, y) || block_door(x, y))) {
1028                 /* Diagonal moves into a door are not allowed. */
1029                 if (mode == DO_MOVE) {
1030                     if (Blind)
1031                         feel_location(x, y);
1032                     if (Underwater || iflags.mention_walls)
1033 /*JP
1034                         You_cant("move diagonally into an intact doorway.");
1035 */
1036                         You_cant("\89ó\82ê\82Ä\82¢\82È\82¢\94à\82É\8eÎ\82ß\82É\88Ú\93®\82·\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
1037                 }
1038                 return FALSE;
1039             }
1040         }
1041     }
1042     if (dx && dy && bad_rock(youmonst.data, ux, y)
1043         && bad_rock(youmonst.data, x, uy)) {
1044         /* Move at a diagonal. */
1045         switch (cant_squeeze_thru(&youmonst)) {
1046         case 3:
1047             if (mode == DO_MOVE)
1048 /*JP
1049                 You("cannot pass that way.");
1050 */
1051                 You("\92Ê\82è\82Ê\82¯\82Å\82«\82È\82¢\81D");
1052             return FALSE;
1053         case 2:
1054             if (mode == DO_MOVE)
1055 /*JP
1056                 You("are carrying too much to get through.");
1057 */
1058                 pline("\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\92Ê\82è\82Ê\82¯\82ç\82ê\82È\82¢\81D");
1059             return FALSE;
1060         case 1:
1061             if (mode == DO_MOVE)
1062 /*JP
1063                 Your("body is too large to fit through.");
1064 */
1065                 Your("\91Ì\82ª\91å\82«\82·\82¬\82Ä\92Ê\82è\82Ê\82¯\82ç\82ê\82È\82¢\81D");
1066             return FALSE;
1067         default:
1068             break; /* can squeeze through */
1069         }
1070     } else if (dx && dy && worm_cross(ux, uy, x, y)) {
1071         /* consecutive long worm segments are at <ux,y> and <x,uy> */
1072         if (mode == DO_MOVE)
1073 /*JP
1074             pline("%s is in your way.", Monnam(m_at(ux, y)));
1075 */
1076             pline("\93¹\82Ì\93r\92\86\82É%s\82ª\82¢\82é\81D", Monnam(m_at(ux, y)));
1077         return FALSE;
1078     }
1079     /* Pick travel path that does not require crossing a trap.
1080      * Avoid water and lava using the usual running rules.
1081      * (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
1082     if (context.run == 8 && (mode != DO_MOVE)
1083         && (x != u.ux || y != u.uy)) {
1084         struct trap *t = t_at(x, y);
1085
1086         if ((t && t->tseen)
1087             || (!Levitation && !Flying && !is_clinger(youmonst.data)
1088                 && is_pool_or_lava(x, y) && levl[x][y].seenv))
1089             return (mode == TEST_TRAP);
1090     }
1091
1092     if (mode == TEST_TRAP)
1093         return FALSE; /* do not move through traps */
1094
1095     ust = &levl[ux][uy];
1096
1097     /* Now see if other things block our way . . */
1098     if (dx && dy && !Passes_walls && IS_DOOR(ust->typ)
1099         && (!doorless_door(ux, uy) || block_entry(x, y))) {
1100         /* Can't move at a diagonal out of a doorway with door. */
1101         if (mode == DO_MOVE && iflags.mention_walls)
1102 /*JP
1103             You_cant("move diagonally out of an intact doorway.");
1104 */
1105             You_cant("\89ó\82ê\82Ä\82¢\82È\82¢\94à\82©\82ç\8eÎ\82ß\82É\88Ú\93®\82·\82é\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
1106         return FALSE;
1107     }
1108
1109     if (sobj_at(BOULDER, x, y) && (Sokoban || !Passes_walls)) {
1110         if (!(Blind || Hallucination) && (context.run >= 2)
1111             && mode != TEST_TRAV) {
1112             if (mode == DO_MOVE && iflags.mention_walls)
1113 /*JP
1114                 pline("A boulder blocks your path.");
1115 */
1116                 pline("\8b\90\8aâ\82ª\93¹\82ð\82Ó\82³\82¢\82Å\82¢\82é\81D");
1117             return FALSE;
1118         }
1119         if (mode == DO_MOVE) {
1120             /* tunneling monsters will chew before pushing */
1121             if (tunnels(youmonst.data) && !needspick(youmonst.data)
1122                 && !Sokoban) {
1123                 if (still_chewing(x, y))
1124                     return FALSE;
1125             } else if (moverock() < 0)
1126                 return FALSE;
1127         } else if (mode == TEST_TRAV) {
1128             struct obj *obj;
1129
1130             /* never travel through boulders in Sokoban */
1131             if (Sokoban)
1132                 return FALSE;
1133
1134             /* don't pick two boulders in a row, unless there's a way thru */
1135             if (sobj_at(BOULDER, ux, uy) && !Sokoban) {
1136                 if (!Passes_walls
1137                     && !(tunnels(youmonst.data) && !needspick(youmonst.data))
1138                     && !carrying(PICK_AXE) && !carrying(DWARVISH_MATTOCK)
1139                     && !((obj = carrying(WAN_DIGGING))
1140                          && !objects[obj->otyp].oc_name_known))
1141                     return FALSE;
1142             }
1143         }
1144         /* assume you'll be able to push it when you get there... */
1145     }
1146
1147     /* OK, it is a legal place to move. */
1148     return TRUE;
1149 }
1150
1151 /*
1152  * Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
1153  * A shortest path is returned.  If guess is TRUE, consider various
1154  * inaccessible locations as valid intermediate path points.
1155  * Returns TRUE if a path was found.
1156  */
1157 STATIC_OVL boolean
1158 findtravelpath(mode)
1159 int mode;
1160 {
1161     /* if travel to adjacent, reachable location, use normal movement rules */
1162     if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && context.travel1
1163         && distmin(u.ux, u.uy, u.tx, u.ty) == 1
1164         && !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) {
1165         context.run = 0;
1166         if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) {
1167             if (mode == TRAVP_TRAVEL) {
1168                 u.dx = u.tx - u.ux;
1169                 u.dy = u.ty - u.uy;
1170                 nomul(0);
1171                 iflags.travelcc.x = iflags.travelcc.y = 0;
1172             }
1173             return TRUE;
1174         }
1175         if (mode == TRAVP_TRAVEL)
1176             context.run = 8;
1177     }
1178     if (u.tx != u.ux || u.ty != u.uy) {
1179         xchar travel[COLNO][ROWNO];
1180         xchar travelstepx[2][COLNO * ROWNO];
1181         xchar travelstepy[2][COLNO * ROWNO];
1182         xchar tx, ty, ux, uy;
1183         int n = 1;      /* max offset in travelsteps */
1184         int set = 0;    /* two sets current and previous */
1185         int radius = 1; /* search radius */
1186         int i;
1187
1188         /* If guessing, first find an "obvious" goal location.  The obvious
1189          * goal is the position the player knows of, or might figure out
1190          * (couldsee) that is closest to the target on a straight path.
1191          */
1192         if (mode == TRAVP_GUESS || mode == TRAVP_VALID) {
1193             tx = u.ux;
1194             ty = u.uy;
1195             ux = u.tx;
1196             uy = u.ty;
1197         } else {
1198             tx = u.tx;
1199             ty = u.ty;
1200             ux = u.ux;
1201             uy = u.uy;
1202         }
1203
1204  noguess:
1205         (void) memset((genericptr_t) travel, 0, sizeof travel);
1206         travelstepx[0][0] = tx;
1207         travelstepy[0][0] = ty;
1208
1209         while (n != 0) {
1210             int nn = 0;
1211
1212             for (i = 0; i < n; i++) {
1213                 int dir;
1214                 int x = travelstepx[set][i];
1215                 int y = travelstepy[set][i];
1216                 static int ordered[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
1217                 /* no diagonal movement for grid bugs */
1218                 int dirmax = NODIAG(u.umonnum) ? 4 : 8;
1219                 boolean alreadyrepeated = FALSE;
1220
1221                 for (dir = 0; dir < dirmax; ++dir) {
1222                     int nx = x + xdir[ordered[dir]];
1223                     int ny = y + ydir[ordered[dir]];
1224
1225                     /*
1226                      * When guessing and trying to travel as close as possible
1227                      * to an unreachable target space, don't include spaces
1228                      * that would never be picked as a guessed target in the
1229                      * travel matrix describing hero-reachable spaces.
1230                      * This stops travel from getting confused and moving
1231                      * the hero back and forth in certain degenerate
1232                      * configurations of sight-blocking obstacles, e.g.
1233                      *
1234                      *  T         1. Dig this out and carry enough to not be
1235                      *   ####       able to squeeze through diagonal gaps.
1236                      *   #--.---    Stand at @ and target travel at space T.
1237                      *    @.....
1238                      *    |.....
1239                      *
1240                      *  T         2. couldsee() marks spaces marked a and x
1241                      *   ####       as eligible guess spaces to move the hero
1242                      *   a--.---    towards.  Space a is closest to T, so it
1243                      *    @xxxxx    gets chosen.  Travel system moves @ right
1244                      *    |xxxxx    to travel to space a.
1245                      *
1246                      *  T         3. couldsee() marks spaces marked b, c and x
1247                      *   ####       as eligible guess spaces to move the hero
1248                      *   a--c---    towards.  Since findtravelpath() is called
1249                      *    b@xxxx    repeatedly during travel, it doesn't
1250                      *    |xxxxx    remember that it wanted to go to space a,
1251                      *              so in comparing spaces b and c, b is
1252                      *              chosen, since it seems like the closest
1253                      *              eligible space to T. Travel system moves @
1254                      *              left to go to space b.
1255                      *
1256                      *            4. Go to 2.
1257                      *
1258                      * By limiting the travel matrix here, space a in the
1259                      * example above is never included in it, preventing
1260                      * the cycle.
1261                      */
1262                     if (!isok(nx, ny)
1263                         || ((mode == TRAVP_GUESS) && !couldsee(nx, ny)))
1264                         continue;
1265                     if ((!Passes_walls && !can_ooze(&youmonst)
1266                          && closed_door(x, y)) || sobj_at(BOULDER, x, y)
1267                         || test_move(x, y, nx-x, ny-y, TEST_TRAP)) {
1268                         /* closed doors and boulders usually
1269                          * cause a delay, so prefer another path */
1270                         if (travel[x][y] > radius - 3) {
1271                             if (!alreadyrepeated) {
1272                                 travelstepx[1 - set][nn] = x;
1273                                 travelstepy[1 - set][nn] = y;
1274                                 /* don't change travel matrix! */
1275                                 nn++;
1276                                 alreadyrepeated = TRUE;
1277                             }
1278                             continue;
1279                         }
1280                     }
1281                     if (test_move(x, y, nx - x, ny - y, TEST_TRAV)
1282                         && (levl[nx][ny].seenv
1283                             || (!Blind && couldsee(nx, ny)))) {
1284                         if (nx == ux && ny == uy) {
1285                             if (mode == TRAVP_TRAVEL || mode == TRAVP_VALID) {
1286                                 u.dx = x - ux;
1287                                 u.dy = y - uy;
1288                                 if (mode == TRAVP_TRAVEL
1289                                     && x == u.tx && y == u.ty) {
1290                                     nomul(0);
1291                                     /* reset run so domove run checks work */
1292                                     context.run = 8;
1293                                     iflags.travelcc.x = iflags.travelcc.y = 0;
1294                                 }
1295                                 return TRUE;
1296                             }
1297                         } else if (!travel[nx][ny]) {
1298                             travelstepx[1 - set][nn] = nx;
1299                             travelstepy[1 - set][nn] = ny;
1300                             travel[nx][ny] = radius;
1301                             nn++;
1302                         }
1303                     }
1304                 }
1305             }
1306
1307 #ifdef DEBUG
1308             if (iflags.trav_debug) {
1309                 /* Use of warning glyph is arbitrary. It stands out. */
1310                 tmp_at(DISP_ALL, warning_to_glyph(1));
1311                 for (i = 0; i < nn; ++i) {
1312                     tmp_at(travelstepx[1 - set][i], travelstepy[1 - set][i]);
1313                 }
1314                 delay_output();
1315                 if (flags.runmode == RUN_CRAWL) {
1316                     delay_output();
1317                     delay_output();
1318                 }
1319                 tmp_at(DISP_END, 0);
1320             }
1321 #endif /* DEBUG */
1322
1323             n = nn;
1324             set = 1 - set;
1325             radius++;
1326         }
1327
1328         /* if guessing, find best location in travel matrix and go there */
1329         if (mode == TRAVP_GUESS) {
1330             int px = tx, py = ty; /* pick location */
1331             int dist, nxtdist, d2, nd2;
1332
1333             dist = distmin(ux, uy, tx, ty);
1334             d2 = dist2(ux, uy, tx, ty);
1335             for (tx = 1; tx < COLNO; ++tx)
1336                 for (ty = 0; ty < ROWNO; ++ty)
1337                     if (travel[tx][ty]) {
1338                         nxtdist = distmin(ux, uy, tx, ty);
1339                         if (nxtdist == dist && couldsee(tx, ty)) {
1340                             nd2 = dist2(ux, uy, tx, ty);
1341                             if (nd2 < d2) {
1342                                 /* prefer non-zigzag path */
1343                                 px = tx;
1344                                 py = ty;
1345                                 d2 = nd2;
1346                             }
1347                         } else if (nxtdist < dist && couldsee(tx, ty)) {
1348                             px = tx;
1349                             py = ty;
1350                             dist = nxtdist;
1351                             d2 = dist2(ux, uy, tx, ty);
1352                         }
1353                     }
1354
1355             if (px == u.ux && py == u.uy) {
1356                 /* no guesses, just go in the general direction */
1357                 u.dx = sgn(u.tx - u.ux);
1358                 u.dy = sgn(u.ty - u.uy);
1359                 if (test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE))
1360                     return TRUE;
1361                 goto found;
1362             }
1363 #ifdef DEBUG
1364             if (iflags.trav_debug) {
1365                 /* Use of warning glyph is arbitrary. It stands out. */
1366                 tmp_at(DISP_ALL, warning_to_glyph(2));
1367                 tmp_at(px, py);
1368                 delay_output();
1369                 if (flags.runmode == RUN_CRAWL) {
1370                     delay_output();
1371                     delay_output();
1372                     delay_output();
1373                     delay_output();
1374                 }
1375                 tmp_at(DISP_END, 0);
1376             }
1377 #endif /* DEBUG */
1378             tx = px;
1379             ty = py;
1380             ux = u.ux;
1381             uy = u.uy;
1382             set = 0;
1383             n = radius = 1;
1384             mode = TRAVP_TRAVEL;
1385             goto noguess;
1386         }
1387         return FALSE;
1388     }
1389
1390  found:
1391     u.dx = 0;
1392     u.dy = 0;
1393     nomul(0);
1394     return FALSE;
1395 }
1396
1397 boolean
1398 is_valid_travelpt(x,y)
1399 int x,y;
1400 {
1401     int tx = u.tx;
1402     int ty = u.ty;
1403     boolean ret;
1404     int g = glyph_at(x,y);
1405     if (x == u.ux && y == u.uy)
1406         return TRUE;
1407     if (isok(x,y) && glyph_is_cmap(g) && S_stone == glyph_to_cmap(g)
1408         && !levl[x][y].seenv)
1409         return FALSE;
1410     u.tx = x;
1411     u.ty = y;
1412     ret = findtravelpath(TRAVP_VALID);
1413     u.tx = tx;
1414     u.ty = ty;
1415     return ret;
1416 }
1417
1418 /* try to escape being stuck in a trapped state by walking out of it;
1419    return true iff moving should continue to intended destination
1420    (all failures and most successful escapes leave hero at original spot) */
1421 STATIC_OVL boolean
1422 trapmove(x, y, desttrap)
1423 int x, y;              /* targetted destination, <u.ux+u.dx,u.uy+u.dy> */
1424 struct trap *desttrap; /* nonnull if another trap at <x,y> */
1425 {
1426     boolean anchored = FALSE;
1427     const char *predicament, *culprit;
1428     char *steedname = !u.usteed ? (char *) 0 : y_monnam(u.usteed);
1429
1430     if (!u.utrap)
1431         return TRUE; /* sanity check */
1432
1433     /*
1434      * Note: caller should call reset_utrap() when we set u.utrap to 0.
1435      */
1436
1437     switch (u.utraptype) {
1438     case TT_BEARTRAP:
1439         if (flags.verbose) {
1440 /*JP
1441             predicament = "caught in a bear trap";
1442 */
1443             predicament = "\8cF\82Ìã©\82É\82Â\82©\82Ü\82Á\82½";
1444             if (u.usteed)
1445 /*JP
1446                 Norep("%s is %s.", upstart(steedname), predicament);
1447 */
1448                 Norep("%s\82Í%s\81D", upstart(steedname), predicament);
1449             else
1450 /*JP
1451                 Norep("You are %s.", predicament);
1452 */
1453                 Norep("\82 \82È\82½\82Í%s\81D", predicament);
1454         }
1455         /* [why does diagonal movement give quickest escape?] */
1456         if ((u.dx && u.dy) || !rn2(5))
1457             u.utrap--;
1458         if (!u.utrap)
1459             goto wriggle_free;
1460         break;
1461     case TT_PIT:
1462         if (desttrap && desttrap->tseen
1463             && is_pit(desttrap->ttyp))
1464             return TRUE; /* move into adjacent pit */
1465         /* try to escape; position stays same regardless of success */
1466         climb_pit();
1467         break;
1468     case TT_WEB:
1469         if (uwep && uwep->oartifact == ART_STING) {
1470             /* escape trap but don't move and don't destroy it */
1471             u.utrap = 0; /* caller will call reset_utrap() */
1472 /*JP
1473             pline("Sting cuts through the web!");
1474 */
1475             pline("\83X\83e\83B\83\93\83O\82Í\82­\82à\82Ì\91\83\82ð\90Ø\82è\82³\82¢\82½\81I");
1476             break;
1477         }
1478         if (--u.utrap) {
1479             if (flags.verbose) {
1480 /*JP
1481                 predicament = "stuck to the web";
1482 */
1483                 predicament = "\82­\82à\82Ì\91\83\82É\82Ð\82Á\82©\82©\82Á\82½";
1484                 if (u.usteed)
1485 /*JP
1486                     Norep("%s is %s.", upstart(steedname), predicament);
1487 */
1488                     Norep("%s\82Í%s\81D", upstart(steedname), predicament);
1489                 else
1490 /*JP
1491                     Norep("You are %s.", predicament);
1492 */
1493                     Norep("\82 \82È\82½\82Í%s\81D", predicament);
1494             }
1495         } else {
1496             if (u.usteed)
1497 /*JP
1498                 pline("%s breaks out of the web.", upstart(steedname));
1499 */
1500                 pline("%s\82Í\82­\82à\82Ì\91\83\82ð\89ó\82µ\82½\81D", upstart(steedname));
1501             else
1502 /*JP
1503                 You("disentangle yourself.");
1504 */
1505                 You("\8e©\95ª\82Å\82Ù\82Ç\82¢\82½\81D");
1506         }
1507         break;
1508     case TT_LAVA:
1509         if (flags.verbose) {
1510 /*JP
1511             predicament = "stuck in the lava";
1512 */
1513             predicament = "\97n\8aâ\82É\82Í\82Ü\82Á\82½";
1514             if (u.usteed)
1515 /*JP
1516                 Norep("%s is %s.", upstart(steedname), predicament);
1517 */
1518                 Norep("%s\82Í%s\81D", upstart(steedname), predicament);
1519             else
1520 /*JP
1521                 Norep("You are %s.", predicament);
1522 */
1523                 Norep("\82 \82È\82½\82Í%s\81D", predicament);
1524         }
1525         if (!is_lava(x, y)) {
1526             u.utrap--;
1527             if ((u.utrap & 0xff) == 0) {
1528                 u.utrap = 0;
1529                 if (u.usteed)
1530 #if 0 /*JP:T*/
1531                     You("lead %s to the edge of the %s.", steedname,
1532                         hliquid("lava"));
1533 #else
1534                     You("%s\82ð%s\82Ì\92[\82Ü\82Å\93±\82¢\82½\81D", steedname,
1535                         hliquid("\97n\8aâ"));
1536 #endif
1537                 else
1538 #if 0 /*JP:T*/
1539                     You("pull yourself to the edge of the %s.",
1540                         hliquid("lava"));
1541 #else
1542                     You("%s\82Ì\92[\82Ü\82Å\82©\82ë\82¤\82\82Ä\81C\82½\82Ç\82è\82Â\82¢\82½\81D",
1543                         hliquid("\97n\8aâ"));
1544 #endif
1545             }
1546         }
1547         u.umoved = TRUE;
1548         break;
1549     case TT_INFLOOR:
1550     case TT_BURIEDBALL:
1551         anchored = (u.utraptype == TT_BURIEDBALL);
1552         if (anchored) {
1553             coord cc;
1554
1555             cc.x = u.ux, cc.y = u.uy;
1556             /* can move normally within radius 1 of buried ball */
1557             if (buried_ball(&cc) && dist2(x, y, cc.x, cc.y) <= 2) {
1558                 /* ugly hack: we need to issue some message here
1559                    in case "you are chained to the buried ball"
1560                    was the most recent message given, otherwise
1561                    our next attempt to move out of tether range
1562                    after this successful move would have its
1563                    can't-do-that message suppressed by Norep */
1564                 if (flags.verbose)
1565 /*JP
1566                     Norep("You move within the chain's reach.");
1567 */
1568                     Norep("\8d½\82ª\93Í\82­\94Í\88Í\82É\88Ú\93®\82Å\82«\82é\81D");
1569                 return TRUE;
1570             }
1571         }
1572         if (--u.utrap) {
1573             if (flags.verbose) {
1574                 if (anchored) {
1575 #if 0 /*JP*/
1576                     predicament = "chained to the";
1577                     culprit = "buried ball";
1578 #else
1579                     predicament = "\82Æ\82Â\82È\82ª\82Á\82Ä\82¢\82é";
1580                     culprit = "\96\84\82Ü\82Á\82Ä\82¢\82é\8b\85";
1581 #endif
1582                 } else {
1583 #if 0 /*JP*/
1584                     predicament = "stuck in the";
1585                     culprit = surface(u.ux, u.uy);
1586 #else
1587                     predicament = "\82É\96\84\82Ü\82Á\82Ä\82¢\82é";
1588                     culprit = surface(u.ux, u.uy);
1589 #endif
1590                 }
1591                 if (u.usteed) {
1592                     if (anchored)
1593 #if 0 /*JP*/
1594                         Norep("You and %s are %s %s.", steedname, predicament,
1595                               culprit);
1596 #else
1597                         Norep("\82 \82È\82½\82Æ%s\82Í%s%s\81D", steedname, culprit,
1598                               predicament);
1599 #endif
1600                     else
1601 #if 0 /*JP*/
1602                         Norep("%s is %s %s.", upstart(steedname), predicament,
1603                               culprit);
1604 #else
1605                         Norep("%s\82Í%s%s\81D", steedname, culprit,
1606                               predicament);
1607 #endif
1608                 } else
1609 /*JP
1610                     Norep("You are %s %s.", predicament, culprit);
1611 */
1612                     Norep("\82 \82È\82½\82Í%s\82É%s\81D", culprit, predicament);
1613             }
1614         } else {
1615  wriggle_free:
1616             if (u.usteed)
1617 #if 0 /*JP:T*/
1618                 pline("%s finally %s free.", upstart(steedname),
1619                       !anchored ? "lurches" : "wrenches the ball");
1620 #else
1621                 pline("%s\82Í%s\82â\82Á\82Æ\8e©\97R\82É\82È\82Á\82½\81D", upstart(steedname),
1622                       !anchored ? "\82à\82ª\82¢\82Ä" : "\93S\8b\85\82ð\82à\82¬\8eæ\82Á\82Ä");
1623 #endif
1624             else
1625 #if 0 /*JP:T*/
1626                 You("finally %s free.",
1627                     !anchored ? "wriggle" : "wrench the ball");
1628 #else
1629                 You("%s\82â\82Á\82Æ\8e©\97R\82É\82È\82Á\82½\81D",
1630                     !anchored ? "\82à\82ª\82¢\82Ä" : "\93S\8b\85\82ð\82à\82¬\8eæ\82Á\82Ä");
1631 #endif
1632             if (anchored)
1633                 buried_ball_to_punishment();
1634         }
1635         break;
1636     default:
1637         impossible("trapmove: stuck in unknown trap? (%d)",
1638                    (int) u.utraptype);
1639         break;
1640     }
1641     return FALSE;
1642 }
1643
1644 boolean
1645 u_rooted()
1646 {
1647     if (!youmonst.data->mmove) {
1648 #if 0 /*JP*/
1649         You("are rooted %s.",
1650             Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
1651                 ? "in place"
1652                 : "to the ground");
1653 #else
1654         You("\82»\82Ì\8fê\82É\97§\82¿\82·\82­\82ñ\82¾\81D");
1655 #endif
1656         nomul(0);
1657         return TRUE;
1658     }
1659     return FALSE;
1660 }
1661
1662 void
1663 domove()
1664 {
1665         int ux1 = u.ux, uy1 = u.uy;
1666
1667         domove_succeeded = 0L;
1668         domove_core();
1669         /* domove_succeeded is available for making assessments now */
1670         if ((domove_succeeded & (DOMOVE_RUSH | DOMOVE_WALK)) != 0)
1671             maybe_smudge_engr(ux1, uy1, u.ux, u.uy);
1672         domove_attempting = 0L;
1673 }
1674
1675 void
1676 domove_core()
1677 {
1678     register struct monst *mtmp;
1679     register struct rm *tmpr;
1680     register xchar x, y;
1681     struct trap *trap = NULL;
1682     int wtcap;
1683     boolean on_ice;
1684     xchar chainx = 0, chainy = 0,
1685           ballx = 0, bally = 0;         /* ball&chain new positions */
1686     int bc_control = 0;                 /* control for ball&chain */
1687     boolean cause_delay = FALSE;        /* dragging ball will skip a move */
1688
1689     if (context.travel) {
1690         if (!findtravelpath(FALSE))
1691             (void) findtravelpath(TRUE);
1692         context.travel1 = 0;
1693     }
1694
1695     if (((wtcap = near_capacity()) >= OVERLOADED
1696          || (wtcap > SLT_ENCUMBER
1697              && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1698                         : (u.uhp < 10 && u.uhp != u.uhpmax))))
1699         && !Is_airlevel(&u.uz)) {
1700         if (wtcap < OVERLOADED) {
1701 /*JP
1702             You("don't have enough stamina to move.");
1703 */
1704             You("\82Ö\82Æ\82Ö\82Æ\82Å\93®\82¯\82È\82¢\81D");
1705             exercise(A_CON, FALSE);
1706         } else
1707 /*JP
1708             You("collapse under your load.");
1709 */
1710             pline("\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\93|\82ê\82½\81D");
1711         nomul(0);
1712         return;
1713     }
1714     if (u.uswallow) {
1715         u.dx = u.dy = 0;
1716         u.ux = x = u.ustuck->mx;
1717         u.uy = y = u.ustuck->my;
1718         mtmp = u.ustuck;
1719     } else {
1720         if (Is_airlevel(&u.uz) && rn2(4) && !Levitation && !Flying) {
1721             switch (rn2(3)) {
1722             case 0:
1723 /*JP
1724                 You("tumble in place.");
1725 */
1726                 You("\82»\82Ì\8fê\82Å\93|\82ê\82½\81D");
1727                 exercise(A_DEX, FALSE);
1728                 break;
1729             case 1:
1730 /*JP
1731                 You_cant("control your movements very well.");
1732 */
1733                 You("\82¤\82Ü\82­\95à\82¯\82È\82¢\81D");
1734                 break;
1735             case 2:
1736 /*JP
1737                 pline("It's hard to walk in thin air.");
1738 */
1739                 pline("\8bó\92\86\82ð\95à\82­\82Ì\82Í\93ï\82µ\82¢\81D");
1740                 exercise(A_DEX, TRUE);
1741                 break;
1742             }
1743             return;
1744         }
1745
1746         /* check slippery ice */
1747         on_ice = !Levitation && is_ice(u.ux, u.uy);
1748         if (on_ice) {
1749             static int skates = 0;
1750
1751             if (!skates)
1752                 skates = find_skates();
1753             if ((uarmf && uarmf->otyp == skates) || resists_cold(&youmonst)
1754                 || Flying || is_floater(youmonst.data)
1755                 || is_clinger(youmonst.data) || is_whirly(youmonst.data)) {
1756                 on_ice = FALSE;
1757             } else if (!rn2(Cold_resistance ? 3 : 2)) {
1758                 HFumbling |= FROMOUTSIDE;
1759                 HFumbling &= ~TIMEOUT;
1760                 HFumbling += 1; /* slip on next move */
1761             }
1762         }
1763         if (!on_ice && (HFumbling & FROMOUTSIDE))
1764             HFumbling &= ~FROMOUTSIDE;
1765
1766         x = u.ux + u.dx;
1767         y = u.uy + u.dy;
1768         if (Stunned || (Confusion && !rn2(5))) {
1769             register int tries = 0;
1770
1771             do {
1772                 if (tries++ > 50) {
1773                     nomul(0);
1774                     return;
1775                 }
1776                 confdir();
1777                 x = u.ux + u.dx;
1778                 y = u.uy + u.dy;
1779             } while (!isok(x, y) || bad_rock(youmonst.data, x, y));
1780         }
1781         /* turbulence might alter your actual destination */
1782         if (u.uinwater) {
1783             water_friction();
1784             if (!u.dx && !u.dy) {
1785                 nomul(0);
1786                 return;
1787             }
1788             x = u.ux + u.dx;
1789             y = u.uy + u.dy;
1790
1791             /* are we trying to move out of water while carrying too much? */
1792             if (isok(x, y) && !is_pool(x, y) && !Is_waterlevel(&u.uz)
1793                 && wtcap > (Swimming ? MOD_ENCUMBER : SLT_ENCUMBER)) {
1794                 /* when escaping from drowning you need to be unencumbered
1795                    in order to crawl out of water, but when not drowning,
1796                    doing so while encumbered is feasible; if in an aquatic
1797                    form, stressed or less is allowed; otherwise (magical
1798                    breathing), only burdened is allowed */
1799 /*JP
1800                 You("are carrying too much to climb out of the water.");
1801 */
1802                 You("\90\85\82©\82ç\8fã\82ª\82é\82É\82Í\89×\95¨\82ð\8e\9d\82¿\82·\82¬\82Ä\82¢\82é\81D");
1803                 nomul(0);
1804                 return;
1805             }
1806         }
1807         if (!isok(x, y)) {
1808             nomul(0);
1809             return;
1810         }
1811         if (((trap = t_at(x, y)) && trap->tseen)
1812             || (Blind && !Levitation && !Flying && !is_clinger(youmonst.data)
1813                 && is_pool_or_lava(x, y) && levl[x][y].seenv)) {
1814             if (context.run >= 2) {
1815                 if (iflags.mention_walls) {
1816                     if (trap && trap->tseen) {
1817                         int tt = what_trap(trap->ttyp, rn2_on_display_rng);
1818
1819 /*JP
1820                         You("stop in front of %s.",
1821 */
1822                         You("%s\82Ì\8eè\91O\82Å\8e~\82Ü\82Á\82½\81D",
1823                             an(defsyms[trap_to_defsym(tt)].explanation));
1824                     } else if (is_pool_or_lava(x,y) && levl[x][y].seenv) {
1825 #if 0 /*JP*/
1826                         You("stop at the edge of the %s.",
1827                             hliquid(is_pool(x,y) ? "water" : "lava"));
1828 #else
1829                         You("%s\82Ì\92[\82Å\8e~\82Ü\82Á\82½\81D.",
1830                             hliquid(is_pool(x,y) ? "\90\85" : "\97n\8aâ"));
1831 #endif
1832                     }
1833                 }
1834                 nomul(0);
1835                 context.move = 0;
1836                 return;
1837             } else
1838                 nomul(0);
1839         }
1840
1841         if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
1842             if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
1843                 /* perhaps it fled (or was teleported or ... ) */
1844                 u.ustuck = 0;
1845             } else if (sticks(youmonst.data)) {
1846                 /* When polymorphed into a sticking monster,
1847                  * u.ustuck means it's stuck to you, not you to it.
1848                  */
1849 /*JP
1850                 You("release %s.", mon_nam(u.ustuck));
1851 */
1852                 You("%s\82ð\95ú\82µ\82½\81D", mon_nam(u.ustuck));
1853                 u.ustuck = 0;
1854             } else {
1855                 /* If holder is asleep or paralyzed:
1856                  *      37.5% chance of getting away,
1857                  *      12.5% chance of waking/releasing it;
1858                  * otherwise:
1859                  *       7.5% chance of getting away.
1860                  * [strength ought to be a factor]
1861                  * If holder is tame and there is no conflict,
1862                  * guaranteed escape.
1863                  */
1864                 switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
1865                 case 0:
1866                 case 1:
1867                 case 2:
1868  pull_free:
1869 /*JP
1870                     You("pull free from %s.", mon_nam(u.ustuck));
1871 */
1872                     You("%s\82ð\82Ð\82«\82Í\82È\82µ\82½\81D", mon_nam(u.ustuck));
1873                     u.ustuck = 0;
1874                     break;
1875                 case 3:
1876                     if (!u.ustuck->mcanmove) {
1877                         /* it's free to move on next turn */
1878                         u.ustuck->mfrozen = 1;
1879                         u.ustuck->msleeping = 0;
1880                     }
1881                 /*FALLTHRU*/
1882                 default:
1883                     if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf)
1884                         goto pull_free;
1885 /*JP
1886                     You("cannot escape from %s!", mon_nam(u.ustuck));
1887 */
1888                     You("%s\82©\82ç\93¦\82°\82ç\82ê\82È\82¢\81I", mon_nam(u.ustuck));
1889                     nomul(0);
1890                     return;
1891                 }
1892             }
1893         }
1894
1895         mtmp = m_at(x, y);
1896         if (mtmp && !is_safepet(mtmp)) {
1897             /* Don't attack if you're running, and can see it */
1898             /* It's fine to displace pets, though */
1899             /* We should never get here if forcefight */
1900             if (context.run && ((!Blind && mon_visible(mtmp)
1901                                  && ((M_AP_TYPE(mtmp) != M_AP_FURNITURE
1902                                       && M_AP_TYPE(mtmp) != M_AP_OBJECT)
1903                                      || Protection_from_shape_changers))
1904                                 || sensemon(mtmp))) {
1905                 nomul(0);
1906                 context.move = 0;
1907                 return;
1908             }
1909         }
1910     }
1911
1912     u.ux0 = u.ux;
1913     u.uy0 = u.uy;
1914     bhitpos.x = x;
1915     bhitpos.y = y;
1916     tmpr = &levl[x][y];
1917
1918     /* attack monster */
1919     if (mtmp) {
1920         /* don't stop travel when displacing pets; if the
1921            displace fails for some reason, attack() in uhitm.c
1922            will stop travel rather than domove */
1923         if (!is_safepet(mtmp) || context.forcefight)
1924             nomul(0);
1925         /* only attack if we know it's there */
1926         /* or if we used the 'F' command to fight blindly */
1927         /* or if it hides_under, in which case we call attack() to print
1928          * the Wait! message.
1929          * This is different from ceiling hiders, who aren't handled in
1930          * attack().
1931          */
1932
1933         /* If they used a 'm' command, trying to move onto a monster
1934          * prints the below message and wastes a turn.  The exception is
1935          * if the monster is unseen and the player doesn't remember an
1936          * invisible monster--then, we fall through to attack() and
1937          * attack_check(), which still wastes a turn, but prints a
1938          * different message and makes the player remember the monster.
1939          */
1940         if (context.nopick && !context.travel
1941             && (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))) {
1942             if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers
1943                 && !sensemon(mtmp))
1944                 stumble_onto_mimic(mtmp);
1945             else if (mtmp->mpeaceful && !Hallucination)
1946                 /* m_monnam(): "dog" or "Fido", no "invisible dog" or "it" */
1947 /*JP
1948                 pline("Pardon me, %s.", m_monnam(mtmp));
1949 */
1950                 pline("\82¿\82å\82Á\82Æ\82²\82ß\82ñ\82È\82³\82¢\82æ\81C%s\82³\82ñ\81D", m_monnam(mtmp));
1951             else
1952 /*JP
1953                 You("move right into %s.", mon_nam(mtmp));
1954 */
1955                 You("%s\82Ì\82»\82Î\82É\88Ú\93®\82µ\82½\81D", mon_nam(mtmp));
1956             return;
1957         }
1958         if (context.forcefight || !mtmp->mundetected || sensemon(mtmp)
1959             || ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)
1960                 && !is_safepet(mtmp))) {
1961             /* try to attack; note that it might evade */
1962             /* also, we don't attack tame when _safepet_ */
1963             if (attack(mtmp))
1964                 return;
1965         }
1966     }
1967
1968     if (context.forcefight && levl[x][y].typ == IRONBARS && uwep) {
1969         struct obj *obj = uwep;
1970
1971         if (breaktest(obj)) {
1972             if (obj->quan > 1L)
1973                 obj = splitobj(obj, 1L);
1974             else
1975                 setuwep((struct obj *)0);
1976             freeinv(obj);
1977         }
1978         hit_bars(&obj, u.ux, u.uy, x, y, TRUE, TRUE);
1979         return;
1980     }
1981
1982     /* specifying 'F' with no monster wastes a turn */
1983     if (context.forcefight
1984         /* remembered an 'I' && didn't use a move command */
1985         || (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
1986         struct obj *boulder = 0;
1987         boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
1988                 solid = !accessible(x, y);
1989         int glyph = glyph_at(x, y); /* might be monster */
1990         char buf[BUFSZ];
1991
1992         if (!Underwater) {
1993             boulder = sobj_at(BOULDER, x, y);
1994             /* if a statue is displayed at the target location,
1995                player is attempting to attack it [and boulder
1996                handling below is suitable for handling that] */
1997             if (glyph_is_statue(glyph)
1998                 || (Hallucination && glyph_is_monster(glyph)))
1999                 boulder = sobj_at(STATUE, x, y);
2000
2001             /* force fight at boulder/statue or wall/door while wielding
2002                pick:  start digging to break the boulder or wall */
2003             if (context.forcefight
2004                 /* can we dig? */
2005                 && uwep && dig_typ(uwep, x, y)
2006                 /* should we dig? */
2007                 && !glyph_is_invisible(glyph) && !glyph_is_monster(glyph)) {
2008                 (void) use_pick_axe2(uwep);
2009                 return;
2010             }
2011         }
2012
2013         /* about to become known empty -- remove 'I' if present */
2014         unmap_object(x, y);
2015         if (boulder)
2016             map_object(boulder, TRUE);
2017         newsym(x, y);
2018         glyph = glyph_at(x, y); /* might have just changed */
2019
2020         if (boulder) {
2021             Strcpy(buf, ansimpleoname(boulder));
2022         } else if (Underwater && !is_pool(x, y)) {
2023             /* Underwater, targetting non-water; the map just shows blank
2024                because you don't see remembered terrain while underwater;
2025                although the hero can attack an adjacent monster this way,
2026                assume he can't reach out far enough to distinguish terrain */
2027 #if 0 /*JP*/
2028             Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
2029                              ? "an air bubble"
2030                              : "nothing");
2031 #else
2032             Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
2033                              ? "\8bó\8bC\82Ì\96A"
2034                              : "\89½\82à\82È\82¢\82Æ\82±\82ë");
2035 #endif
2036         } else if (solid) {
2037             /* glyph might indicate unseen terrain if hero is blind;
2038                unlike searching, this won't reveal what that terrain is
2039                (except for solid rock, where the glyph would otherwise
2040                yield ludicrous "dark part of a room") */
2041 #if 0 /*JP*/
2042             Strcpy(buf, (levl[x][y].typ == STONE) ? "solid rock"
2043                          : glyph_is_cmap(glyph)
2044                             ? the(defsyms[glyph_to_cmap(glyph)].explanation)
2045                             : (const char *) "an unknown obstacle");
2046 #else
2047             Strcpy(buf, (levl[x][y].typ == STONE) ? "\90Î"
2048                          : glyph_is_cmap(glyph)
2049                             ? the(defsyms[glyph_to_cmap(glyph)].explanation)
2050                             : (const char *) "\95s\96¾\82È\8fá\8aQ\95¨");
2051 #endif
2052             /* note: 'solid' is misleadingly named and catches pools
2053                of water and lava as well as rock and walls */
2054         } else {
2055 /*JP
2056             Strcpy(buf, "thin air");
2057 */
2058             Strcpy(buf, "\89½\82à\82È\82¢\8bó\92\86");
2059         }
2060 #if 0 /*JP*/
2061         You("%s%s %s.",
2062             !(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ",
2063             explo ? "explode at" : "attack", buf);
2064 #else
2065         You("%s%s%s.",
2066             !(boulder || solid) ? "" : !explo ? "\8cø\89Ê\82È\82­" : "\82Þ\82¾\82É",
2067             buf, explo ? "\82Å\94\9a\94­\82µ\82½" : "\82ð\8dU\8c\82\82µ\82½");
2068 #endif
2069
2070         nomul(0);
2071         if (explo) {
2072             wake_nearby();
2073             u.mh = -1; /* dead in the current form */
2074             rehumanize();
2075         }
2076         return;
2077     }
2078     (void) unmap_invisible(x, y);
2079     /* not attacking an animal, so we try to move */
2080     if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
2081         nomul(0);
2082         return;
2083     }
2084
2085     if (u_rooted())
2086         return;
2087
2088     if (u.utrap) {
2089         boolean moved = trapmove(x, y, trap);
2090
2091         if (!u.utrap)
2092             reset_utrap(TRUE); /* might resume levitation or flight */
2093         /* might not have escaped, or did escape but remain in same spot */
2094         if (!moved)
2095             return;
2096     }
2097
2098     if (!test_move(u.ux, u.uy, x - u.ux, y - u.uy, DO_MOVE)) {
2099         if (!context.door_opened) {
2100             context.move = 0;
2101             nomul(0);
2102         }
2103         return;
2104     }
2105
2106     /* Move ball and chain.  */
2107     if (Punished)
2108         if (!drag_ball(x, y, &bc_control, &ballx, &bally, &chainx, &chainy,
2109                        &cause_delay, TRUE))
2110             return;
2111
2112     /* Check regions entering/leaving */
2113     if (!in_out_region(x, y))
2114         return;
2115
2116     /* now move the hero */
2117     mtmp = m_at(x, y);
2118     u.ux += u.dx;
2119     u.uy += u.dy;
2120     /* Move your steed, too */
2121     if (u.usteed) {
2122         u.usteed->mx = u.ux;
2123         u.usteed->my = u.uy;
2124         exercise_steed();
2125     }
2126
2127     /*
2128      * If safepet at destination then move the pet to the hero's
2129      * previous location using the same conditions as in attack().
2130      * there are special extenuating circumstances:
2131      * (1) if the pet dies then your god angers,
2132      * (2) if the pet gets trapped then your god may disapprove,
2133      * (3) if the pet was already trapped and you attempt to free it
2134      * not only do you encounter the trap but you may frighten your
2135      * pet causing it to go wild!  moral: don't abuse this privilege.
2136      *
2137      * Ceiling-hiding pets are skipped by this section of code, to
2138      * be caught by the normal falling-monster code.
2139      */
2140     if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
2141         /* if trapped, there's a chance the pet goes wild */
2142         if (mtmp->mtrapped) {
2143             if (!rn2(mtmp->mtame)) {
2144                 mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
2145                 if (mtmp->mleashed)
2146                     m_unleash(mtmp, TRUE);
2147                 growl(mtmp);
2148             } else {
2149                 yelp(mtmp);
2150             }
2151         }
2152
2153         /* seemimic/newsym should be done before moving hero, otherwise
2154            the display code will draw the hero here before we possibly
2155            cancel the swap below (we can ignore steed mx,my here) */
2156         u.ux = u.ux0, u.uy = u.uy0;
2157         mtmp->mundetected = 0;
2158         if (M_AP_TYPE(mtmp))
2159             seemimic(mtmp);
2160         else if (!mtmp->mtame)
2161             newsym(mtmp->mx, mtmp->my);
2162         u.ux = mtmp->mx, u.uy = mtmp->my; /* resume swapping positions */
2163
2164         if (mtmp->mtrapped && (trap = t_at(mtmp->mx, mtmp->my)) != 0
2165             && is_pit(trap->ttyp)
2166             && sobj_at(BOULDER, trap->tx, trap->ty)) {
2167             /* can't swap places with pet pinned in a pit by a boulder */
2168             u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
2169             if (u.usteed)
2170                 u.usteed->mx = u.ux, u.usteed->my = u.uy;
2171         } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
2172             /* can't swap places when pet can't move to your spot */
2173             u.ux = u.ux0, u.uy = u.uy0;
2174             if (u.usteed)
2175                 u.usteed->mx = u.ux, u.usteed->my = u.uy;
2176 /*JP
2177             You("stop.  %s can't move diagonally.", upstart(y_monnam(mtmp)));
2178 */
2179             You("\8e~\82Ü\82Á\82½\81D%s\82Í\8eÎ\82ß\82É\93®\82¯\82È\82¢\81D", upstart(y_monnam(mtmp)));
2180         } else if (u.ux0 != x && u.uy0 != y && bad_rock(mtmp->data, x, u.uy0)
2181                    && bad_rock(mtmp->data, u.ux0, y)
2182                    && (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
2183             /* can't swap places when pet won't fit thru the opening */
2184             u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
2185             if (u.usteed)
2186                 u.usteed->mx = u.ux, u.usteed->my = u.uy;
2187 /*JP
2188             You("stop.  %s won't fit through.", upstart(y_monnam(mtmp)));
2189 */
2190             You("\8e~\82Ü\82Á\82½\81D%s\82Í\92Ê\82è\94²\82¯\82ç\82ê\82È\82¢\81D", upstart(y_monnam(mtmp)));
2191         } else {
2192             char pnambuf[BUFSZ];
2193
2194             /* save its current description in case of polymorph */
2195             Strcpy(pnambuf, y_monnam(mtmp));
2196             mtmp->mtrapped = 0;
2197             remove_monster(x, y);
2198             place_monster(mtmp, u.ux0, u.uy0);
2199             newsym(x, y);
2200             newsym(u.ux0, u.uy0);
2201
2202 #if 0 /*JP*/
2203             You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
2204                 pnambuf);
2205 #else
2206             You("%s%s\82½\81D",
2207                 pnambuf,
2208                 mtmp->mtame ? "\82Æ\8fê\8f\8a\82ð\93ü\82ê\8a·\82í\82Á" : "\82ð\95|\82ª\82ç\82¹");
2209 #endif
2210
2211             /* check for displacing it into pools and traps */
2212             switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
2213             case 0:
2214                 break;
2215             case 1: /* trapped */
2216             case 3: /* changed levels */
2217                 /* there's already been a trap message, reinforce it */
2218                 abuse_dog(mtmp);
2219                 adjalign(-3);
2220                 break;
2221             case 2:
2222                 /* drowned or died...
2223                  * you killed your pet by direct action, so get experience
2224                  * and possibly penalties;
2225                  * we want the level gain message, if it happens, to occur
2226                  * before the guilt message below
2227                  */
2228                 {
2229                     /* minliquid() and mintrap() call mondead() rather than
2230                        killed() so we duplicate some of the latter here */
2231                     int tmp, mndx;
2232
2233                     u.uconduct.killer++;
2234                     mndx = monsndx(mtmp->data);
2235                     tmp = experience(mtmp, (int) mvitals[mndx].died);
2236                     more_experienced(tmp, 0);
2237                     newexplevel(); /* will decide if you go up */
2238                 }
2239                 /* That's no way to treat a pet!  Your god gets angry.
2240                  *
2241                  * [This has always been pretty iffy.  Why does your
2242                  * patron deity care at all, let alone enough to get mad?]
2243                  */
2244                 if (rn2(4)) {
2245 /*JP
2246                     You_feel("guilty about losing your pet like this.");
2247 */
2248                     pline("\82±\82Ì\82æ\82¤\82È\8c`\82Å\83y\83b\83g\82ð\8e¸\82¤\82Æ\82Í\8dß\90[\82¢\82±\82Æ\82¾\82Æ\8ev\82Á\82½\81D");
2249                     u.ugangr++;
2250                     adjalign(-15);
2251                 }
2252                 break;
2253             default:
2254                 pline("that's strange, unknown mintrap result!");
2255                 break;
2256             }
2257         }
2258     }
2259
2260     reset_occupations();
2261     if (context.run) {
2262         if (context.run < 8)
2263             if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ)
2264                 || IS_FURNITURE(tmpr->typ))
2265                 nomul(0);
2266     }
2267
2268     if (hides_under(youmonst.data) || youmonst.data->mlet == S_EEL
2269         || u.dx || u.dy)
2270         (void) hideunder(&youmonst);
2271
2272     /*
2273      * Mimics (or whatever) become noticeable if they move and are
2274      * imitating something that doesn't move.  We could extend this
2275      * to non-moving monsters...
2276      */
2277     if ((u.dx || u.dy) && (U_AP_TYPE == M_AP_OBJECT
2278                            || U_AP_TYPE == M_AP_FURNITURE))
2279         youmonst.m_ap_type = M_AP_NOTHING;
2280
2281     check_leash(u.ux0, u.uy0);
2282
2283     if (u.ux0 != u.ux || u.uy0 != u.uy) {
2284         /* let caller know so that an evaluation may take place */
2285         domove_succeeded |= (domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK));
2286         u.umoved = TRUE;
2287         /* Clean old position -- vision_recalc() will print our new one. */
2288         newsym(u.ux0, u.uy0);
2289         /* Since the hero has moved, adjust what can be seen/unseen. */
2290         vision_recalc(1); /* Do the work now in the recover time. */
2291         invocation_message();
2292     }
2293
2294     if (Punished) /* put back ball and chain */
2295         move_bc(0, bc_control, ballx, bally, chainx, chainy);
2296
2297     if (u.umoved)
2298         spoteffects(TRUE);
2299
2300     /* delay next move because of ball dragging */
2301     /* must come after we finished picking up, in spoteffects() */
2302     if (cause_delay) {
2303         nomul(-2);
2304 /*JP
2305         multi_reason = "dragging an iron ball";
2306 */
2307         multi_reason = "\93S\8b\85\82É\88ø\82«\82¸\82ç\82ê\82Ä\82¢\82é\8e\9e\82É";
2308         nomovemsg = "";
2309     }
2310
2311     if (context.run && flags.runmode != RUN_TPORT) {
2312         /* display every step or every 7th step depending upon mode */
2313         if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
2314             if (flags.time)
2315                 context.botl = 1;
2316             curs_on_u();
2317             delay_output();
2318             if (flags.runmode == RUN_CRAWL) {
2319                 delay_output();
2320                 delay_output();
2321                 delay_output();
2322                 delay_output();
2323             }
2324         }
2325     }
2326 }
2327
2328 void
2329 maybe_smudge_engr(x1,y1,x2,y2)
2330 int x1, y1, x2, y2;
2331 {
2332     struct engr *ep;
2333
2334     if (can_reach_floor(TRUE)) {
2335         if ((ep = engr_at(x1, y1)) && ep->engr_type != HEADSTONE)
2336             wipe_engr_at(x1, y1, rnd(5), FALSE);
2337         if ((x2 != x1 || y2 != y1)
2338                 && (ep = engr_at(x2, y2)) && ep->engr_type != HEADSTONE)
2339             wipe_engr_at(x2, y2, rnd(5), FALSE);
2340     }
2341 }
2342
2343 /* combat increases metabolism */
2344 boolean
2345 overexertion()
2346 {
2347     /* this used to be part of domove() when moving to a monster's
2348        position, but is now called by attack() so that it doesn't
2349        execute if you decline to attack a peaceful monster */
2350     gethungry();
2351     if ((moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) {
2352         int *hp = (!Upolyd ? &u.uhp : &u.mh);
2353
2354         if (*hp > 1) {
2355             *hp -= 1;
2356         } else {
2357 /*JP
2358             You("pass out from exertion!");
2359 */
2360             You("\8bC\90â\82µ\82½\81D");
2361             exercise(A_CON, FALSE);
2362             fall_asleep(-10, FALSE);
2363         }
2364     }
2365     return (boolean) (multi < 0); /* might have fainted (forced to sleep) */
2366 }
2367
2368 void
2369 invocation_message()
2370 {
2371     /* a special clue-msg when on the Invocation position */
2372     if (invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
2373         char buf[BUFSZ];
2374         struct obj *otmp = carrying(CANDELABRUM_OF_INVOCATION);
2375
2376         nomul(0); /* stop running or travelling */
2377         if (u.usteed)
2378 /*JP
2379             Sprintf(buf, "beneath %s", y_monnam(u.usteed));
2380 */
2381             Sprintf(buf, "%s\82Ì\89º\82É", y_monnam(u.usteed));
2382         else if (Levitation || Flying)
2383 /*JP
2384             Strcpy(buf, "beneath you");
2385 */
2386             Strcpy(buf, "\89º\95û\82É");
2387         else
2388 /*JP
2389             Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
2390 */
2391             Strcpy(buf, "\91«\8c³\82É");
2392
2393 /*JP
2394         You_feel("a strange vibration %s.", buf);
2395 */
2396         You("%s\8aï\96­\82È\90U\93®\82ð\8a´\82\82½\81D", buf);
2397         u.uevent.uvibrated = 1;
2398         if (otmp && otmp->spe == 7 && otmp->lamplit)
2399 #if 0 /*JP*/
2400             pline("%s %s!", The(xname(otmp)),
2401                   Blind ? "throbs palpably" : "glows with a strange light");
2402 #else
2403             pline("%s\82Í%s\82µ\82½\81I", The(xname(otmp)),
2404                   Blind ? "\82©\82·\82©\82É\90U\93®" : "\8aï\96­\82È\8cõ\82ð\94­");
2405 #endif
2406     }
2407 }
2408
2409 /* moving onto different terrain;
2410    might be going into solid rock, inhibiting levitation or flight,
2411    or coming back out of such, reinstating levitation/flying */
2412 void
2413 switch_terrain()
2414 {
2415     struct rm *lev = &levl[u.ux][u.uy];
2416     boolean blocklev = (IS_ROCK(lev->typ) || closed_door(u.ux, u.uy)
2417                         || (Is_waterlevel(&u.uz) && lev->typ == WATER)),
2418             was_levitating = !!Levitation, was_flying = !!Flying;
2419
2420     if (blocklev) {
2421         /* called from spoteffects(), stop levitating but skip float_down() */
2422         if (Levitation)
2423 /*JP
2424             You_cant("levitate in here.");
2425 */
2426             You_cant("\82±\82±\82Å\82Í\95\82\97V\82Å\82«\82È\82¢\81D");
2427         BLevitation |= FROMOUTSIDE;
2428     } else if (BLevitation) {
2429         BLevitation &= ~FROMOUTSIDE;
2430         /* we're probably levitating now; if not, we must be chained
2431            to a buried iron ball so get float_up() feedback for that */
2432         if (Levitation || BLevitation)
2433             float_up();
2434     }
2435     /* the same terrain that blocks levitation also blocks flight */
2436     if (blocklev) {
2437         if (Flying)
2438 /*JP
2439             You_cant("fly in here.");
2440 */
2441             You_cant("\82±\82±\82Å\82Í\94ò\82×\82È\82¢\81D");
2442         BFlying |= FROMOUTSIDE;
2443     } else if (BFlying) {
2444         BFlying &= ~FROMOUTSIDE;
2445         float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
2446         /* [minor bug: we don't know whether this is beginning flight or
2447            resuming it; that could be tracked so that this message could
2448            be adjusted to "resume flying", but isn't worth the effort...] */
2449         if (Flying)
2450 /*JP
2451             You("start flying.");
2452 */
2453             You("\94ò\82Ñ\82Í\82\82ß\82½\81D");
2454     }
2455     if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
2456         context.botl = TRUE; /* update Lev/Fly status condition */
2457 }
2458
2459 /* extracted from spoteffects; called by spoteffects to check for entering or
2460    leaving a pool of water/lava, and by moveloop to check for staying on one;
2461    returns true to skip rest of spoteffects */
2462 boolean
2463 pooleffects(newspot)
2464 boolean newspot;             /* true if called by spoteffects */
2465 {
2466     /* check for leaving water */
2467     if (u.uinwater) {
2468         boolean still_inwater = FALSE; /* assume we're getting out */
2469
2470         if (!is_pool(u.ux, u.uy)) {
2471             if (Is_waterlevel(&u.uz))
2472 /*JP
2473                 You("pop into an air bubble.");
2474 */
2475                 You("\82Ð\82å\82¢\82Æ\8bó\8bC\82Ì\96A\82É\93ü\82Á\82½\81D");
2476             else if (is_lava(u.ux, u.uy))
2477 #if 0 /*JP*/
2478                 You("leave the %s...", hliquid("water")); /* oops! */
2479 #else
2480                 You("%s\90\85\82©\82ç\94²\82¯\82¾\82µ\82½\81D\81D\81D", hliquid("\90\85"));  /* oops! */
2481 #endif
2482             else
2483 #if 0 /*JP*/
2484                 You("are on solid %s again.",
2485                     is_ice(u.ux, u.uy) ? "ice" : "land");
2486 #else
2487                 You("\8cÅ\82¢%s\82Ì\8fã\82É\82Ü\82½\96ß\82Á\82½\81D",
2488                     is_ice(u.ux, u.uy) ? "\95X" : "\92n\96Ê");
2489 #endif
2490         } else if (Is_waterlevel(&u.uz)) {
2491             still_inwater = TRUE;
2492         } else if (Levitation) {
2493 /*JP
2494             You("pop out of the %s like a cork!", hliquid("water"));
2495 */
2496             You("\83R\83\8b\83N\82Ì\82æ\82¤\82É%s\82©\82ç\94ò\82Ñ\82¾\82µ\82½\81I", hliquid("\90\85"));
2497         } else if (Flying) {
2498 /*JP
2499             You("fly out of the %s.", hliquid("water"));
2500 */
2501             You("%s\82©\82ç\94ò\82Ñ\82¾\82µ\82½\81D", hliquid("\90\85"));
2502         } else if (Wwalking) {
2503 /*JP
2504             You("slowly rise above the surface.");
2505 */
2506             You("\82ä\82Á\82­\82è\90\85\96Ê\82Ü\82Å\8fã\82ª\82Á\82½\81D");
2507         } else {
2508             still_inwater = TRUE;
2509         }
2510         if (!still_inwater) {
2511             boolean was_underwater = (Underwater && !Is_waterlevel(&u.uz));
2512
2513             u.uinwater = 0;       /* leave the water */
2514             if (was_underwater) { /* restore vision */
2515                 docrt();
2516                 vision_full_recalc = 1;
2517             }
2518         }
2519     }
2520
2521     /* check for entering water or lava */
2522     if (!u.ustuck && !Levitation && !Flying && is_pool_or_lava(u.ux, u.uy)) {
2523         if (u.usteed
2524             && (is_flyer(u.usteed->data) || is_floater(u.usteed->data)
2525                 || is_clinger(u.usteed->data))) {
2526             /* floating or clinging steed keeps hero safe (is_flyer() test
2527                is redundant; it can't be true since Flying yielded false) */
2528             return FALSE;
2529         } else if (u.usteed) {
2530             /* steed enters pool */
2531             dismount_steed(Underwater ? DISMOUNT_FELL : DISMOUNT_GENERIC);
2532             /* dismount_steed() -> float_down() -> pickup()
2533                (float_down doesn't do autopickup on Air or Water) */
2534             if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
2535                 return FALSE;
2536             /* even if we actually end up at same location, float_down()
2537                has already done spoteffect()'s trap and pickup actions */
2538             if (newspot)
2539                 check_special_room(FALSE); /* spoteffects */
2540             return TRUE;
2541         }
2542         /* not mounted */
2543
2544         /* drown(),lava_effects() return true if hero changes
2545            location while surviving the problem */
2546         if (is_lava(u.ux, u.uy)) {
2547             if (lava_effects())
2548                 return TRUE;
2549         } else if (!Wwalking
2550                    && (newspot || !u.uinwater || !(Swimming || Amphibious))) {
2551             if (drown())
2552                 return TRUE;
2553         }
2554     }
2555     return FALSE;
2556 }
2557
2558 void
2559 spoteffects(pick)
2560 boolean pick;
2561 {
2562     static int inspoteffects = 0;
2563     static coord spotloc;
2564     static int spotterrain;
2565     static struct trap *spottrap = (struct trap *) 0;
2566     static unsigned spottraptyp = NO_TRAP;
2567
2568     struct monst *mtmp;
2569     struct trap *trap = t_at(u.ux, u.uy);
2570     int trapflag = iflags.failing_untrap ? FAILEDUNTRAP : 0;
2571
2572     /* prevent recursion from affecting the hero all over again
2573        [hero poly'd to iron golem enters water here, drown() inflicts
2574        damage that triggers rehumanize() which calls spoteffects()...] */
2575     if (inspoteffects && u.ux == spotloc.x && u.uy == spotloc.y
2576         /* except when reason is transformed terrain (ice -> water) */
2577         && spotterrain == levl[u.ux][u.uy].typ
2578         /* or transformed trap (land mine -> pit) */
2579         && (!spottrap || !trap || trap->ttyp == spottraptyp))
2580         return;
2581
2582     ++inspoteffects;
2583     spotterrain = levl[u.ux][u.uy].typ;
2584     spotloc.x = u.ux, spotloc.y = u.uy;
2585
2586     /* moving onto different terrain might cause Lev or Fly to toggle */
2587     if (spotterrain != levl[u.ux0][u.uy0].typ || !on_level(&u.uz, &u.uz0))
2588         switch_terrain();
2589
2590     if (pooleffects(TRUE))
2591         goto spotdone;
2592
2593     check_special_room(FALSE);
2594     if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
2595         dosinkfall();
2596     if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
2597         boolean pit;
2598
2599         /* if levitation is due to time out at the end of this
2600            turn, allowing it to do so could give the perception
2601            that a trap here is being triggered twice, so adjust
2602            the timeout to prevent that */
2603         if (trap && (HLevitation & TIMEOUT) == 1L
2604             && !(ELevitation || (HLevitation & ~(I_SPECIAL | TIMEOUT)))) {
2605             if (rn2(2)) { /* defer timeout */
2606                 incr_itimeout(&HLevitation, 1L);
2607             } else { /* timeout early */
2608                 if (float_down(I_SPECIAL | TIMEOUT, 0L)) {
2609                     /* levitation has ended; we've already triggered
2610                        any trap and [usually] performed autopickup */
2611                     trap = 0;
2612                     pick = FALSE;
2613                 }
2614             }
2615         }
2616         /*
2617          * If not a pit, pickup before triggering trap.
2618          * If pit, trigger trap before pickup.
2619          */
2620         pit = (trap && is_pit(trap->ttyp));
2621         if (pick && !pit)
2622             (void) pickup(1);
2623
2624         if (trap) {
2625             /*
2626              * dotrap on a fire trap calls melt_ice() which triggers
2627              * spoteffects() (again) which can trigger the same fire
2628              * trap (again). Use static spottrap to prevent that.
2629              * We track spottraptyp because some traps morph
2630              * (landmine to pit) and any new trap type
2631              * should get triggered.
2632              */
2633             if (!spottrap || spottraptyp != trap->ttyp) {
2634                 spottrap = trap;
2635                 spottraptyp = trap->ttyp;
2636                 dotrap(trap, trapflag); /* fall into arrow trap, etc. */
2637                 spottrap = (struct trap *) 0;
2638                 spottraptyp = NO_TRAP;
2639             }
2640         }
2641         if (pick && pit)
2642             (void) pickup(1);
2643     }
2644     /* Warning alerts you to ice danger */
2645     if (Warning && is_ice(u.ux, u.uy)) {
2646         static const char *const icewarnings[] = {
2647 #if 0 /*JP*/
2648             "The ice seems very soft and slushy.",
2649             "You feel the ice shift beneath you!",
2650             "The ice, is gonna BREAK!", /* The Dead Zone */
2651 #else
2652             "\95X\82Í\82Æ\82Ä\82à\93î\82ç\82©\82­\82Ä\97n\82¯\82»\82¤\82¾\81D",
2653             "\82 \82È\82½\82Ì\89º\82Ì\95X\82ª\93®\82¢\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I",
2654             "\95X\82ª\89ó\82ê\82é\82¼\81I", /* The Dead Zone */
2655 #endif
2656         };
2657         long time_left = spot_time_left(u.ux, u.uy, MELT_ICE_AWAY);
2658
2659         if (time_left && time_left < 15L)
2660             pline("%s", icewarnings[(time_left < 5L) ? 2
2661                                     : (time_left < 10L) ? 1
2662                                       : 0]);
2663     }
2664     if ((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) {
2665         mtmp->mundetected = mtmp->msleeping = 0;
2666         switch (mtmp->data->mlet) {
2667         case S_PIERCER:
2668 #if 0 /*JP*/
2669             pline("%s suddenly drops from the %s!", Amonnam(mtmp),
2670                   ceiling(u.ux, u.uy));
2671 #else
2672             pline("%s\82ª\93Ë\91R%s\82©\82ç\97\8e\82¿\82Ä\82«\82½\81I", Amonnam(mtmp),
2673                   ceiling(u.ux,u.uy));
2674 #endif
2675             if (mtmp->mtame) { /* jumps to greet you, not attack */
2676                 ;
2677             } else if (uarmh && is_metallic(uarmh)) {
2678 /*JP
2679                 pline("Its blow glances off your %s.",
2680 */
2681                 pline("\8dU\8c\82\82Í\82 \82È\82½\82Ì%s\82ð\82©\82·\82ß\82½\82¾\82¯\82¾\82Á\82½\81D",
2682                       helm_simple_name(uarmh));
2683             } else if (u.uac + 3 <= rnd(20)) {
2684 #if 0 /*JP:T*/
2685                 You("are almost hit by %s!",
2686                     x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE));
2687 #else
2688                 You("\97\8e\82¿\82Ä\82«\82½%s\82É\82à\82¤\8f­\82µ\82Å\93\96\82½\82é\82Æ\82±\82ë\82¾\82Á\82½\81D",
2689                     x_monnam(mtmp, ARTICLE_A, "", 0, TRUE));
2690 #endif
2691             } else {
2692                 int dmg;
2693
2694 #if 0 /*JP*/
2695                 You("are hit by %s!",
2696                     x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE));
2697 #else
2698                 You("\97\8e\82¿\82Ä\82«\82½%s\82É\93\96\82½\82Á\82½\81I",
2699                     x_monnam(mtmp, ARTICLE_A, "", 0, TRUE));
2700 #endif
2701                 dmg = d(4, 6);
2702                 if (Half_physical_damage)
2703                     dmg = (dmg + 1) / 2;
2704                 mdamageu(mtmp, dmg);
2705             }
2706             break;
2707         default: /* monster surprises you. */
2708             if (mtmp->mtame)
2709 #if 0 /*JP*/
2710                 pline("%s jumps near you from the %s.", Amonnam(mtmp),
2711                       ceiling(u.ux, u.uy));
2712 #else
2713                 pline("%s\82ª%s\82©\82ç\82 \82È\82½\82Ì\8bß\82­\82É\94ò\82ñ\82Å\82«\82½\81D", Amonnam(mtmp),
2714                       ceiling(u.ux,u.uy));
2715 #endif
2716             else if (mtmp->mpeaceful) {
2717 /*JP
2718                 You("surprise %s!",
2719 */
2720                 You("%s\82ð\8bÁ\82©\82µ\82½\81I",
2721                     Blind && !sensemon(mtmp) ? something : a_monnam(mtmp));
2722                 mtmp->mpeaceful = 0;
2723             } else
2724 /*JP
2725                 pline("%s attacks you by surprise!", Amonnam(mtmp));
2726 */
2727                 pline("%s\82Í\8bÁ\82¢\82Ä\82 \82È\82½\82ð\8dU\8c\82\82µ\82½\81I", Amonnam(mtmp));
2728             break;
2729         }
2730         mnexto(mtmp); /* have to move the monster */
2731     }
2732  spotdone:
2733     if (!--inspoteffects) {
2734         spotterrain = STONE; /* 0 */
2735         spotloc.x = spotloc.y = 0;
2736     }
2737     return;
2738 }
2739
2740 /* returns first matching monster */
2741 STATIC_OVL struct monst *
2742 monstinroom(mdat, roomno)
2743 struct permonst *mdat;
2744 int roomno;
2745 {
2746     register struct monst *mtmp;
2747
2748     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2749         if (DEADMONSTER(mtmp))
2750             continue;
2751         if (mtmp->data == mdat
2752             && index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET))
2753             return mtmp;
2754     }
2755     return (struct monst *) 0;
2756 }
2757
2758 char *
2759 in_rooms(x, y, typewanted)
2760 register xchar x, y;
2761 register int typewanted;
2762 {
2763     static char buf[5];
2764     char rno, *ptr = &buf[4];
2765     int typefound, min_x, min_y, max_x, max_y_offset, step;
2766     register struct rm *lev;
2767
2768 #define goodtype(rno) \
2769     (!typewanted                                                   \
2770      || (typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted  \
2771      || (typewanted == SHOPBASE && typefound > SHOPBASE))
2772
2773     switch (rno = levl[x][y].roomno) {
2774     case NO_ROOM:
2775         return ptr;
2776     case SHARED:
2777         step = 2;
2778         break;
2779     case SHARED_PLUS:
2780         step = 1;
2781         break;
2782     default: /* i.e. a regular room # */
2783         if (goodtype(rno))
2784             *(--ptr) = rno;
2785         return ptr;
2786     }
2787
2788     min_x = x - 1;
2789     max_x = x + 1;
2790     if (x < 1)
2791         min_x += step;
2792     else if (x >= COLNO)
2793         max_x -= step;
2794
2795     min_y = y - 1;
2796     max_y_offset = 2;
2797     if (min_y < 0) {
2798         min_y += step;
2799         max_y_offset -= step;
2800     } else if ((min_y + max_y_offset) >= ROWNO)
2801         max_y_offset -= step;
2802
2803     for (x = min_x; x <= max_x; x += step) {
2804         lev = &levl[x][min_y];
2805         y = 0;
2806         if ((rno = lev[y].roomno) >= ROOMOFFSET && !index(ptr, rno)
2807             && goodtype(rno))
2808             *(--ptr) = rno;
2809         y += step;
2810         if (y > max_y_offset)
2811             continue;
2812         if ((rno = lev[y].roomno) >= ROOMOFFSET && !index(ptr, rno)
2813             && goodtype(rno))
2814             *(--ptr) = rno;
2815         y += step;
2816         if (y > max_y_offset)
2817             continue;
2818         if ((rno = lev[y].roomno) >= ROOMOFFSET && !index(ptr, rno)
2819             && goodtype(rno))
2820             *(--ptr) = rno;
2821     }
2822     return ptr;
2823 }
2824
2825 /* is (x,y) in a town? */
2826 boolean
2827 in_town(x, y)
2828 register int x, y;
2829 {
2830     s_level *slev = Is_special(&u.uz);
2831     register struct mkroom *sroom;
2832     boolean has_subrooms = FALSE;
2833
2834     if (!slev || !slev->flags.town)
2835         return FALSE;
2836
2837     /*
2838      * See if (x,y) is in a room with subrooms, if so, assume it's the
2839      * town.  If there are no subrooms, the whole level is in town.
2840      */
2841     for (sroom = &rooms[0]; sroom->hx > 0; sroom++) {
2842         if (sroom->nsubrooms > 0) {
2843             has_subrooms = TRUE;
2844             if (inside_room(sroom, x, y))
2845                 return TRUE;
2846         }
2847     }
2848
2849     return !has_subrooms;
2850 }
2851
2852 STATIC_OVL void
2853 move_update(newlev)
2854 register boolean newlev;
2855 {
2856     char *ptr1, *ptr2, *ptr3, *ptr4;
2857
2858     Strcpy(u.urooms0, u.urooms);
2859     Strcpy(u.ushops0, u.ushops);
2860     if (newlev) {
2861         u.urooms[0] = '\0';
2862         u.uentered[0] = '\0';
2863         u.ushops[0] = '\0';
2864         u.ushops_entered[0] = '\0';
2865         Strcpy(u.ushops_left, u.ushops0);
2866         return;
2867     }
2868     Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0));
2869
2870     for (ptr1 = &u.urooms[0], ptr2 = &u.uentered[0], ptr3 = &u.ushops[0],
2871          ptr4 = &u.ushops_entered[0];
2872          *ptr1; ptr1++) {
2873         if (!index(u.urooms0, *ptr1))
2874             *(ptr2++) = *ptr1;
2875         if (IS_SHOP(*ptr1 - ROOMOFFSET)) {
2876             *(ptr3++) = *ptr1;
2877             if (!index(u.ushops0, *ptr1))
2878                 *(ptr4++) = *ptr1;
2879         }
2880     }
2881     *ptr2 = '\0';
2882     *ptr3 = '\0';
2883     *ptr4 = '\0';
2884
2885     /* filter u.ushops0 -> u.ushops_left */
2886     for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++)
2887         if (!index(u.ushops, *ptr1))
2888             *(ptr2++) = *ptr1;
2889     *ptr2 = '\0';
2890 }
2891
2892 /* possibly deliver a one-time room entry message */
2893 void
2894 check_special_room(newlev)
2895 register boolean newlev;
2896 {
2897     register struct monst *mtmp;
2898     char *ptr;
2899
2900     move_update(newlev);
2901
2902     if (*u.ushops0)
2903         u_left_shop(u.ushops_left, newlev);
2904
2905     if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */
2906         return; /* no entrance messages necessary */
2907
2908     /* Did we just enter a shop? */
2909     if (*u.ushops_entered)
2910         u_entered_shop(u.ushops_entered);
2911
2912     for (ptr = &u.uentered[0]; *ptr; ptr++) {
2913         int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype;
2914         boolean msg_given = TRUE;
2915
2916         /* Did we just enter some other special room? */
2917         /* vault.c insists that a vault remain a VAULT,
2918          * and temples should remain TEMPLEs,
2919          * but everything else gives a message only the first time */
2920         switch (rt) {
2921         case ZOO:
2922 /*JP
2923             pline("Welcome to David's treasure zoo!");
2924 */
2925             pline("\83f\83r\83b\83g\95ó\94 \93®\95¨\89\80\82É\82æ\82¤\82±\82»\81I");
2926             break;
2927         case SWAMP:
2928 #if 0 /*JP*/
2929             pline("It %s rather %s down here.", Blind ? "feels" : "looks",
2930                   Blind ? "humid" : "muddy");
2931 #else
2932                     pline("\82©\82È\82è%s\81D",
2933                           Blind ? "\8e¼\8bC\82ª\82 \82é\8fê\8f\8a\82Ì\82æ\82¤\82¾"
2934                                 : "\82Ç\82ë\82Ç\82ë\82µ\82Ä\82¢\82é\8fê\8f\8a\82¾");
2935 #endif
2936             break;
2937         case COURT:
2938 /*JP
2939             You("enter an opulent throne room!");
2940 */
2941             You("\89Ø\82â\82©\82È\8bÊ\8dÀ\82Ì\8aÔ\82É\93ü\82Á\82½\81I");
2942             break;
2943         case LEPREHALL:
2944 /*JP
2945             You("enter a leprechaun hall!");
2946 */
2947             You("\83\8c\83v\83\89\83R\81[\83\93\83z\81[\83\8b\82É\93ü\82Á\82½\81I");
2948             break;
2949         case MORGUE:
2950             if (midnight()) {
2951 #if 0 /*JP*/
2952                 const char *run = locomotion(youmonst.data, "Run");
2953                 pline("%s away!  %s away!", run, run);
2954 #else
2955                 pline("\93¦\82°\82ë\81I\93¦\82°\82ë\81I");
2956 #endif
2957             } else
2958 /*JP
2959                 You("have an uncanny feeling...");
2960 */
2961                 You("\95s\8bC\96¡\82È\8a´\82\82ª\82µ\82½\81D\81D\81D");
2962             break;
2963         case BEEHIVE:
2964 /*JP
2965             You("enter a giant beehive!");
2966 */
2967             You("\8b\90\91å\82È\96I\82Ì\91\83\82É\93ü\82Á\82½\81I");
2968             break;
2969         case COCKNEST:
2970 /*JP
2971             You("enter a disgusting nest!");
2972 */
2973             You("\82Þ\82Á\82Æ\82·\82é\8fL\82¢\82Ì\82·\82é\92¹\82Ì\91\83\82É\93ü\82Á\82½\81I");
2974             break;
2975         case ANTHOLE:
2976 /*JP
2977             You("enter an anthole!");
2978 */
2979             You("\83A\83\8a\82Ì\91\83\82É\93ü\82Á\82½\81I");
2980             break;
2981         case BARRACKS:
2982             if (monstinroom(&mons[PM_SOLDIER], roomno)
2983                 || monstinroom(&mons[PM_SERGEANT], roomno)
2984                 || monstinroom(&mons[PM_LIEUTENANT], roomno)
2985                 || monstinroom(&mons[PM_CAPTAIN], roomno))
2986 /*JP
2987                 You("enter a military barracks!");
2988 */
2989                 You("\8cR\91à\82Ì\95ºäq\82É\93ü\82Á\82½\81I");
2990             else
2991 /*JP
2992                 You("enter an abandoned barracks.");
2993 */
2994                 You("\95ú\92u\82³\82ê\82½\82Ü\82Ü\82Ì\95ºäq\82É\93ü\82Á\82½\81D");
2995             break;
2996         case DELPHI: {
2997             struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
2998             if (oracle) {
2999                 if (!oracle->mpeaceful)
3000 /*JP
3001                     verbalize("You're in Delphi, %s.", plname);
3002 */
3003                     verbalize("\82¨\82Ü\82¦\82Í\83f\83\8b\83t\83@\83C\82Ì\90_\91õ\8f\8a\82É\82¢\82é\81D");
3004                 else
3005 #if 0 /*JP*/
3006                     verbalize("%s, %s, welcome to Delphi!",
3007                               Hello((struct monst *) 0), plname);
3008 #else
3009                     verbalize("\82¨\82¨%s\81C\83f\83\8b\83t\83@\83C\82Ì\90_\91õ\8f\8a\82É\82æ\82­\82¼\82Ü\82¢\82ç\82ê\82½\81I",
3010                               plname);
3011 #endif
3012             } else
3013                 msg_given = FALSE;
3014             break;
3015         }
3016         case TEMPLE:
3017             intemple(roomno + ROOMOFFSET);
3018         /*FALLTHRU*/
3019         default:
3020             msg_given = (rt == TEMPLE);
3021             rt = 0;
3022             break;
3023         }
3024         if (msg_given)
3025             room_discovered(roomno);
3026
3027         if (rt != 0) {
3028             rooms[roomno].rtype = OROOM;
3029             if (!search_special(rt)) {
3030                 /* No more room of that type */
3031                 switch (rt) {
3032                 case COURT:
3033                     level.flags.has_court = 0;
3034                     break;
3035                 case SWAMP:
3036                     level.flags.has_swamp = 0;
3037                     break;
3038                 case MORGUE:
3039                     level.flags.has_morgue = 0;
3040                     break;
3041                 case ZOO:
3042                     level.flags.has_zoo = 0;
3043                     break;
3044                 case BARRACKS:
3045                     level.flags.has_barracks = 0;
3046                     break;
3047                 case TEMPLE:
3048                     level.flags.has_temple = 0;
3049                     break;
3050                 case BEEHIVE:
3051                     level.flags.has_beehive = 0;
3052                     break;
3053                 }
3054             }
3055             if (rt == COURT || rt == SWAMP || rt == MORGUE || rt == ZOO)
3056                 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3057                     if (DEADMONSTER(mtmp))
3058                         continue;
3059                     if (!Stealth && !rn2(3))
3060                         mtmp->msleeping = 0;
3061                 }
3062         }
3063     }
3064
3065     return;
3066 }
3067
3068 /* returns
3069    1 = cannot pickup, time taken
3070    0 = cannot pickup, no time taken
3071   -1 = do normal pickup
3072   -2 = loot the monster */
3073 int
3074 pickup_checks()
3075 {
3076     /* uswallow case added by GAN 01/29/87 */
3077     if (u.uswallow) {
3078         if (!u.ustuck->minvent) {
3079             if (is_animal(u.ustuck->data)) {
3080 /*JP
3081                 You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck)));
3082 */
3083                 You("%s\82Ì\90ã\82ð\8fE\82Á\82½\81D", mon_nam(u.ustuck));
3084 /*JP
3085                 pline("But it's kind of slimy, so you drop it.");
3086 */
3087                 pline("\82µ\82©\82µ\81C\82»\82ê\82Í\82Ê\82é\82Ê\82é\82µ\82Ä\95s\89õ\82¾\82Á\82½\82Ì\82Å\8eÌ\82Ä\82Ä\82µ\82Ü\82Á\82½\81D");
3088             } else
3089 #if 0 /*JP*/
3090                 You("don't %s anything in here to pick up.",
3091                     Blind ? "feel" : "see");
3092 #else
3093                 pline("\82±\82±\82É\82Í\8fE\82¦\82é\82à\82Ì\82ª\82È\82¢%s\81D",
3094                     Blind ? "\82æ\82¤\82¾" : "");
3095 #endif
3096             return 1;
3097         } else {
3098             return -2; /* loot the monster inventory */
3099         }
3100     }
3101     if (is_pool(u.ux, u.uy)) {
3102         if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
3103             || (Flying && !Breathless)) {
3104 #if 0 /*JP:T*/
3105             You("cannot dive into the %s to pick things up.",
3106                 hliquid("water"));
3107 #else
3108             You("\95¨\82ð\8fE\82¢\82 \82°\82é\82½\82ß\82É%s\82É\94ò\82Ñ\82±\82ß\82È\82¢\81D",
3109                 hliquid("\90\85"));
3110 #endif
3111             return 0;
3112         } else if (!Underwater) {
3113 /*JP
3114             You_cant("even see the bottom, let alone pick up %s.", something);
3115 */
3116             pline("\92ê\82³\82¦\8c©\82¦\82È\82¢\81C\8fE\82¤\82Ì\82Í\82â\82ß\82æ\82¤\81D");
3117             return 0;
3118         }
3119     }
3120     if (is_lava(u.ux, u.uy)) {
3121         if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
3122             || (Flying && !Breathless)) {
3123 /*JP
3124             You_cant("reach the bottom to pick things up.");
3125 */
3126             You_cant("\95¨\82ð\8fE\82¢\8fã\82°\82é\82½\82ß\82É\92ê\82Ü\82Å\82¢\82¯\82È\82¢\81D");
3127             return 0;
3128         } else if (!likes_lava(youmonst.data)) {
3129 /*JP
3130             You("would burn to a crisp trying to pick things up.");
3131 */
3132             You("\8fE\82¢\8fã\82°\82æ\82¤\82Æ\82µ\82½\82ç\8aÛ\8fÅ\82°\82É\82È\82Á\82Ä\82µ\82Ü\82¤\82¾\82ë\82¤\81D");
3133             return 0;
3134         }
3135     }
3136     if (!OBJ_AT(u.ux, u.uy)) {
3137         register struct rm *lev = &levl[u.ux][u.uy];
3138
3139         if (IS_THRONE(lev->typ))
3140 /*JP
3141             pline("It must weigh%s a ton!", lev->looted ? " almost" : "");
3142 */
3143             pline("\82±\82ê\82Í%s\8fd\82¢\81I", lev->looted ? "\82©\82È\82è" : "\82·\82²\82­");
3144         else if (IS_SINK(lev->typ))
3145 /*JP
3146             pline_The("plumbing connects it to the floor.");
3147 */
3148             pline_The("\94z\8aÇ\82Í\8f°\82É\82Â\82È\82ª\82Á\82Ä\82¢\82é\81D");
3149         else if (IS_GRAVE(lev->typ))
3150 /*JP
3151             You("don't need a gravestone.  Yet.");
3152 */
3153             pline("\82 \82È\82½\82É\82Í\95æ\90Î\82Í\95s\97v\82¾\81D\81D\81D\8d¡\82Ì\82Æ\82±\82ë\81D");
3154         else if (IS_FOUNTAIN(lev->typ))
3155 /*JP
3156             You("could drink the %s...", hliquid("water"));
3157 */
3158             You("%s\82ð\88ù\82ß\82È\82¢\81D\81D\81D", hliquid("\90\85"));
3159         else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
3160 /*JP
3161             pline("It won't come off the hinges.");
3162 */
3163             pline("\83q\83\93\83W\82ð\8aO\82¹\82È\82¢\81D");
3164         else if (IS_ALTAR(lev->typ))
3165             pline("Moving the altar would be a very bad idea.");
3166         else if (lev->typ == STAIRS)
3167             pline_The("stairs are solidly fixed to the %s.",
3168                       surface(u.ux, u.uy));
3169         else
3170 /*JP
3171             There("is nothing here to pick up.");
3172 */
3173             pline("\82±\82±\82É\82Í\8fE\82¦\82é\82à\82Ì\82Í\82È\82¢\81D");
3174         return 0;
3175     }
3176     if (!can_reach_floor(TRUE)) {
3177         struct trap *traphere = t_at(u.ux, u.uy);
3178         if (traphere && uteetering_at_seen_pit(traphere))
3179 /*JP
3180             You("cannot reach the bottom of the pit.");
3181 */
3182             You("\97\8e\82µ\8c\8a\82Ì\92ê\82É%s\82ª\93Í\82©\82È\82©\82Á\82½\81D", body_part(HAND));
3183         else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
3184             rider_cant_reach();
3185         else if (Blind && !can_reach_floor(TRUE))
3186 /*JP
3187             You("cannot reach anything here.");
3188 */
3189             You("\89½\82É\82à\93Í\82©\82È\82¢\81D");
3190         else
3191 /*JP
3192             You("cannot reach the %s.", surface(u.ux, u.uy));
3193 */
3194             You("%s\82É\82½\82Ç\82è\82Â\82­\82±\82Æ\82ª\82Å\82«\82È\82¢\81D", surface(u.ux, u.uy));
3195         return 0;
3196     }
3197     return -1; /* can do normal pickup */
3198 }
3199
3200 /* the ',' command */
3201 int
3202 dopickup(VOID_ARGS)
3203 {
3204     int count, tmpcount, ret;
3205
3206     /* awful kludge to work around parse()'s pre-decrement */
3207     count = (multi || (save_cm && *save_cm == cmd_from_func(dopickup)))
3208               ? multi + 1 : 0;
3209     multi = 0; /* always reset */
3210
3211     if ((ret = pickup_checks() >= 0))
3212         return ret;
3213     else if (ret == -2) {
3214         tmpcount = -count;
3215         return loot_mon(u.ustuck, &tmpcount, (boolean *) 0);
3216     } /* else ret == -1 */
3217
3218     return pickup(-count);
3219 }
3220
3221 /* stop running if we see something interesting */
3222 /* turn around a corner if that is the only way we can proceed */
3223 /* do not turn left or right twice */
3224 void
3225 lookaround()
3226 {
3227     register int x, y;
3228     int i, x0 = 0, y0 = 0, m0 = 1, i0 = 9;
3229     int corrct = 0, noturn = 0;
3230     struct monst *mtmp;
3231     struct trap *trap;
3232
3233     /* Grid bugs stop if trying to move diagonal, even if blind.  Maybe */
3234     /* they polymorphed while in the middle of a long move. */
3235     if (NODIAG(u.umonnum) && u.dx && u.dy) {
3236 /*JP
3237         You("cannot move diagonally.");
3238 */
3239         You("\8eÎ\82ß\82É\88Ú\93®\82Å\82«\82È\82¢\81D");
3240         nomul(0);
3241         return;
3242     }
3243
3244     if (Blind || context.run == 0)
3245         return;
3246     for (x = u.ux - 1; x <= u.ux + 1; x++)
3247         for (y = u.uy - 1; y <= u.uy + 1; y++) {
3248             if (!isok(x, y) || (x == u.ux && y == u.uy))
3249                 continue;
3250             if (NODIAG(u.umonnum) && x != u.ux && y != u.uy)
3251                 continue;
3252
3253             if ((mtmp = m_at(x, y)) != 0
3254                 && M_AP_TYPE(mtmp) != M_AP_FURNITURE
3255                 && M_AP_TYPE(mtmp) != M_AP_OBJECT
3256                 && (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
3257                 if ((context.run != 1 && !mtmp->mtame)
3258                     || (x == u.ux + u.dx && y == u.uy + u.dy
3259                         && !context.travel)) {
3260                     if (iflags.mention_walls)
3261 /*JP
3262                         pline("%s blocks your path.", upstart(a_monnam(mtmp)));
3263 */
3264                         pline("%s\82ª\93¹\82ð\82Ó\82³\82¢\82Å\82¢\82é\81D", a_monnam(mtmp));
3265                     goto stop;
3266                 }
3267             }
3268
3269             if (levl[x][y].typ == STONE)
3270                 continue;
3271             if (x == u.ux - u.dx && y == u.uy - u.dy)
3272                 continue;
3273
3274             if (IS_ROCK(levl[x][y].typ) || levl[x][y].typ == ROOM
3275                 || IS_AIR(levl[x][y].typ)) {
3276                 continue;
3277             } else if (closed_door(x, y) || (mtmp && is_door_mappear(mtmp))) {
3278                 if (x != u.ux && y != u.uy)
3279                     continue;
3280                 if (context.run != 1) {
3281                     if (iflags.mention_walls)
3282 /*JP
3283                         You("stop in front of the door.");
3284 */
3285                         You("\94à\82Ì\8eè\91O\82Å\8e~\82Ü\82Á\82½\81D");
3286                     goto stop;
3287                 }
3288                 goto bcorr;
3289             } else if (levl[x][y].typ == CORR) {
3290  bcorr:
3291                 if (levl[u.ux][u.uy].typ != ROOM) {
3292                     if (context.run == 1 || context.run == 3
3293                         || context.run == 8) {
3294                         i = dist2(x, y, u.ux + u.dx, u.uy + u.dy);
3295                         if (i > 2)
3296                             continue;
3297                         if (corrct == 1 && dist2(x, y, x0, y0) != 1)
3298                             noturn = 1;
3299                         if (i < i0) {
3300                             i0 = i;
3301                             x0 = x;
3302                             y0 = y;
3303                             m0 = mtmp ? 1 : 0;
3304                         }
3305                     }
3306                     corrct++;
3307                 }
3308                 continue;
3309             } else if ((trap = t_at(x, y)) && trap->tseen) {
3310                 if (context.run == 1)
3311                     goto bcorr; /* if you must */
3312                 if (x == u.ux + u.dx && y == u.uy + u.dy) {
3313                     if (iflags.mention_walls) {
3314                         int tt = what_trap(trap->ttyp, rn2_on_display_rng);
3315 /*JP
3316                         You("stop in front of %s.",
3317 */
3318                         You("%s\82Ì\8eè\91O\82Å\8e~\82Ü\82Á\82½\81D",
3319                             an(defsyms[trap_to_defsym(tt)].explanation));
3320                     }
3321                     goto stop;
3322                 }
3323                 continue;
3324             } else if (is_pool_or_lava(x, y)) {
3325                 /* water and lava only stop you if directly in front, and stop
3326                  * you even if you are running
3327                  */
3328                 if (!Levitation && !Flying && !is_clinger(youmonst.data)
3329                     && x == u.ux + u.dx && y == u.uy + u.dy) {
3330                     /* No Wwalking check; otherwise they'd be able
3331                      * to test boots by trying to SHIFT-direction
3332                      * into a pool and seeing if the game allowed it
3333                      */
3334                     if (iflags.mention_walls)
3335 #if 0 /*JP*/
3336                         You("stop at the edge of the %s.",
3337                             hliquid(is_pool(x,y) ? "water" : "lava"));
3338 #else
3339                         You("%s\82Ì\92[\82Å\8e~\82Ü\82Á\82½\81D",
3340                             hliquid(is_pool(x,y) ? "\90\85" : "\97n\8aâ"));
3341 #endif
3342                     goto stop;
3343                 }
3344                 continue;
3345             } else { /* e.g. objects or trap or stairs */
3346                 if (context.run == 1)
3347                     goto bcorr;
3348                 if (context.run == 8)
3349                     continue;
3350                 if (mtmp)
3351                     continue; /* d */
3352                 if (((x == u.ux - u.dx) && (y != u.uy + u.dy))
3353                     || ((y == u.uy - u.dy) && (x != u.ux + u.dx)))
3354                     continue;
3355             }
3356  stop:
3357             nomul(0);
3358             return;
3359         } /* end for loops */
3360
3361     if (corrct > 1 && context.run == 2) {
3362         if (iflags.mention_walls)
3363 /*JP
3364             pline_The("corridor widens here.");
3365 */
3366             pline("\92Ê\98H\82Í\82±\82±\82Å\8dL\82­\82È\82Á\82Ä\82¢\82é\81D");
3367         goto stop;
3368     }
3369     if ((context.run == 1 || context.run == 3 || context.run == 8) && !noturn
3370         && !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) {
3371         /* make sure that we do not turn too far */
3372         if (i0 == 2) {
3373             if (u.dx == y0 - u.uy && u.dy == u.ux - x0)
3374                 i = 2; /* straight turn right */
3375             else
3376                 i = -2; /* straight turn left */
3377         } else if (u.dx && u.dy) {
3378             if ((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy))
3379                 i = -1; /* half turn left */
3380             else
3381                 i = 1; /* half turn right */
3382         } else {
3383             if ((x0 - u.ux == y0 - u.uy && !u.dy)
3384                 || (x0 - u.ux != y0 - u.uy && u.dy))
3385                 i = 1; /* half turn right */
3386             else
3387                 i = -1; /* half turn left */
3388         }
3389
3390         i += u.last_str_turn;
3391         if (i <= 2 && i >= -2) {
3392             u.last_str_turn = i;
3393             u.dx = x0 - u.ux;
3394             u.dy = y0 - u.uy;
3395         }
3396     }
3397 }
3398
3399 /* check for a doorway which lacks its door (NODOOR or BROKEN) */
3400 STATIC_OVL boolean
3401 doorless_door(x, y)
3402 int x, y;
3403 {
3404     struct rm *lev_p = &levl[x][y];
3405
3406     if (!IS_DOOR(lev_p->typ))
3407         return FALSE;
3408     /* all rogue level doors are doorless but disallow diagonal access, so
3409        we treat them as if their non-existant doors were actually present */
3410     if (Is_rogue_level(&u.uz))
3411         return FALSE;
3412     return !(lev_p->doormask & ~(D_NODOOR | D_BROKEN));
3413 }
3414
3415 /* used by drown() to check whether hero can crawl from water to <x,y> */
3416 boolean
3417 crawl_destination(x, y)
3418 int x, y;
3419 {
3420     /* is location ok in general? */
3421     if (!goodpos(x, y, &youmonst, 0))
3422         return FALSE;
3423
3424     /* orthogonal movement is unrestricted when destination is ok */
3425     if (x == u.ux || y == u.uy)
3426         return TRUE;
3427
3428     /* diagonal movement has some restrictions */
3429     if (NODIAG(u.umonnum))
3430         return FALSE; /* poly'd into a grid bug... */
3431     if (Passes_walls)
3432         return TRUE; /* or a xorn... */
3433     /* pool could be next to a door, conceivably even inside a shop */
3434     if (IS_DOOR(levl[x][y].typ) && (!doorless_door(x, y) || block_door(x, y)))
3435         return FALSE;
3436     /* finally, are we trying to squeeze through a too-narrow gap? */
3437     return !(bad_rock(youmonst.data, u.ux, y)
3438              && bad_rock(youmonst.data, x, u.uy));
3439 }
3440
3441 /* something like lookaround, but we are not running */
3442 /* react only to monsters that might hit us */
3443 int
3444 monster_nearby()
3445 {
3446     register int x, y;
3447     register struct monst *mtmp;
3448
3449     /* Also see the similar check in dochugw() in monmove.c */
3450     for (x = u.ux - 1; x <= u.ux + 1; x++)
3451         for (y = u.uy - 1; y <= u.uy + 1; y++) {
3452             if (!isok(x, y) || (x == u.ux && y == u.uy))
3453                 continue;
3454             if ((mtmp = m_at(x, y)) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
3455                 && M_AP_TYPE(mtmp) != M_AP_OBJECT
3456                 && (!mtmp->mpeaceful || Hallucination)
3457                 && (!is_hider(mtmp->data) || !mtmp->mundetected)
3458                 && !noattacks(mtmp->data) && mtmp->mcanmove
3459                 && !mtmp->msleeping  /* aplvax!jcn */
3460                 && !onscary(u.ux, u.uy, mtmp) && canspotmon(mtmp))
3461                 return 1;
3462         }
3463     return 0;
3464 }
3465
3466 void
3467 nomul(nval)
3468 register int nval;
3469 {
3470     if (multi < nval)
3471         return;              /* This is a bug fix by ab@unido */
3472     u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
3473     u.usleep = 0;
3474     multi = nval;
3475     if (nval == 0)
3476         multi_reason = NULL;
3477     context.travel = context.travel1 = context.mv = context.run = 0;
3478 }
3479
3480 /* called when a non-movement, multi-turn action has completed */
3481 void
3482 unmul(msg_override)
3483 const char *msg_override;
3484 {
3485     multi = 0; /* caller will usually have done this already */
3486     if (msg_override)
3487         nomovemsg = msg_override;
3488     else if (!nomovemsg)
3489         nomovemsg = You_can_move_again;
3490     if (*nomovemsg)
3491         pline("%s", nomovemsg);
3492     nomovemsg = 0;
3493     u.usleep = 0;
3494     multi_reason = NULL;
3495     if (afternmv) {
3496         int NDECL((*f)) = afternmv;
3497
3498         /* clear afternmv before calling it (to override the
3499            encumbrance hack for levitation--see weight_cap()) */
3500         afternmv = (int NDECL((*))) 0;
3501         (void) (*f)();
3502         /* for finishing Armor/Boots/&c_on() */
3503         update_inventory();
3504     }
3505 }
3506
3507 STATIC_OVL void
3508 maybe_wail()
3509 {
3510     static short powers[] = { TELEPORT, SEE_INVIS, POISON_RES, COLD_RES,
3511                               SHOCK_RES, FIRE_RES, SLEEP_RES, DISINT_RES,
3512                               TELEPORT_CONTROL, STEALTH, FAST, INVIS };
3513
3514     if (moves <= wailmsg + 50)
3515         return;
3516
3517     wailmsg = moves;
3518     if (Role_if(PM_WIZARD) || Race_if(PM_ELF) || Role_if(PM_VALKYRIE)) {
3519         const char *who;
3520         int i, powercnt;
3521
3522 #if 0 /*JP*/
3523         who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? urole.name.m
3524                                                            : "Elf";
3525 #else
3526         who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? urole.name.m
3527                                                            : "\83G\83\8b\83t";
3528 #endif
3529         if (u.uhp == 1) {
3530 /*JP
3531             pline("%s is about to die.", who);
3532 */
3533             pline("%s\82Í\8e\80\82É\82©\82¯\82Ä\82¢\82é\81D", who);
3534         } else {
3535             for (i = 0, powercnt = 0; i < SIZE(powers); ++i)
3536                 if (u.uprops[powers[i]].intrinsic & INTRINSIC)
3537                     ++powercnt;
3538
3539 /*JP
3540             pline((powercnt >= 4) ? "%s, all your powers will be lost..."
3541 */
3542             pline((powercnt >= 4) ? "%s\81C\82 \82È\82½\82Ì\91S\82Ä\82Ì\97Í\82Í\8e¸\82í\82ê\82Â\82Â\82 \82é\81D\81D\81D"
3543 /*JP
3544                                 : "%s, your life force is running out.",
3545 */
3546                                 : "%s\81C\82 \82È\82½\82Ì\90\96½\97Í\82Í\90s\82«\82æ\82¤\82Æ\82µ\82Ä\82¢\82é\81D\81D\81D",
3547                   who);
3548         }
3549     } else {
3550 /*JP
3551         You_hear(u.uhp == 1 ? "the wailing of the Banshee..."
3552 */
3553         You_hear(u.uhp == 1 ? "\83o\83\93\83V\81[\82Ì\82·\82·\82è\8b\83\82«\82ª\95·\82±\82¦\82é\81D\81D\81D"
3554 /*JP
3555                             : "the howling of the CwnAnnwn...");
3556 */
3557                             : "\83N\81[\83\93\81E\83A\83\93\83k\81[\83\93\82Ì\89\93\96i\82ª\95·\82±\82¦\82é\81D\81D\81D");
3558     }
3559 }
3560
3561 void
3562 losehp(n, knam, k_format)
3563 register int n;
3564 register const char *knam;
3565 boolean k_format;
3566 {
3567     if (Upolyd) {
3568         u.mh -= n;
3569         if (u.mhmax < u.mh)
3570             u.mhmax = u.mh;
3571         context.botl = 1;
3572         if (u.mh < 1)
3573             rehumanize();
3574         else if (n > 0 && u.mh * 10 < u.mhmax && Unchanging)
3575             maybe_wail();
3576         return;
3577     }
3578
3579     u.uhp -= n;
3580     if (u.uhp > u.uhpmax)
3581         u.uhpmax = u.uhp; /* perhaps n was negative */
3582     else
3583         context.travel = context.travel1 = context.mv = context.run = 0;
3584     context.botl = 1;
3585     if (u.uhp < 1) {
3586         killer.format = k_format;
3587         if (killer.name != knam) /* the thing that killed you */
3588             Strcpy(killer.name, knam ? knam : "");
3589 /*JP
3590         You("die...");
3591 */
3592         pline("\82 \82È\82½\82Í\8e\80\82É\82Ü\82µ\82½\81D\81D\81D");
3593         done(DIED);
3594     } else if (n > 0 && u.uhp * 10 < u.uhpmax) {
3595         maybe_wail();
3596     }
3597 }
3598
3599 int
3600 weight_cap()
3601 {
3602     long carrcap, save_ELev = ELevitation, save_BLev = BLevitation;
3603
3604     /* boots take multiple turns to wear but any properties they
3605        confer are enabled at the start rather than the end; that
3606        causes message sequencing issues for boots of levitation
3607        so defer their encumbrance benefit until they're fully worn */
3608     if (afternmv == Boots_on && (ELevitation & W_ARMF) != 0L) {
3609         ELevitation &= ~W_ARMF;
3610         float_vs_flight(); /* in case Levitation is blocking Flying */
3611     }
3612     /* levitation is blocked by being trapped in the floor, but it still
3613        functions enough in that situation to enhance carrying capacity */
3614     BLevitation &= ~I_SPECIAL;
3615
3616     carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50;
3617     if (Upolyd) {
3618         /* consistent with can_carry() in mon.c */
3619         if (youmonst.data->mlet == S_NYMPH)
3620             carrcap = MAX_CARR_CAP;
3621         else if (!youmonst.data->cwt)
3622             carrcap = (carrcap * (long) youmonst.data->msize) / MZ_HUMAN;
3623         else if (!strongmonst(youmonst.data)
3624                  || (strongmonst(youmonst.data)
3625                      && (youmonst.data->cwt > WT_HUMAN)))
3626             carrcap = (carrcap * (long) youmonst.data->cwt / WT_HUMAN);
3627     }
3628
3629     if (Levitation || Is_airlevel(&u.uz) /* pugh@cornell */
3630         || (u.usteed && strongmonst(u.usteed->data))) {
3631         carrcap = MAX_CARR_CAP;
3632     } else {
3633         if (carrcap > MAX_CARR_CAP)
3634             carrcap = MAX_CARR_CAP;
3635         if (!Flying) {
3636             if (EWounded_legs & LEFT_SIDE)
3637                 carrcap -= 100;
3638             if (EWounded_legs & RIGHT_SIDE)
3639                 carrcap -= 100;
3640         }
3641         if (carrcap < 0)
3642             carrcap = 0;
3643     }
3644
3645     if (ELevitation != save_ELev || BLevitation != save_BLev) {
3646         ELevitation = save_ELev;
3647         BLevitation = save_BLev;
3648         float_vs_flight();
3649     }
3650
3651     return (int) carrcap;
3652 }
3653
3654 static int wc; /* current weight_cap(); valid after call to inv_weight() */
3655
3656 /* returns how far beyond the normal capacity the player is currently. */
3657 /* inv_weight() is negative if the player is below normal capacity. */
3658 int
3659 inv_weight()
3660 {
3661     register struct obj *otmp = invent;
3662     register int wt = 0;
3663
3664     while (otmp) {
3665         if (otmp->oclass == COIN_CLASS)
3666             wt += (int) (((long) otmp->quan + 50L) / 100L);
3667         else if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data))
3668             wt += otmp->owt;
3669         otmp = otmp->nobj;
3670     }
3671     wc = weight_cap();
3672     return (wt - wc);
3673 }
3674
3675 /*
3676  * Returns 0 if below normal capacity, or the number of "capacity units"
3677  * over the normal capacity the player is loaded.  Max is 5.
3678  */
3679 int
3680 calc_capacity(xtra_wt)
3681 int xtra_wt;
3682 {
3683     int cap, wt = inv_weight() + xtra_wt;
3684
3685     if (wt <= 0)
3686         return UNENCUMBERED;
3687     if (wc <= 1)
3688         return OVERLOADED;
3689     cap = (wt * 2 / wc) + 1;
3690     return min(cap, OVERLOADED);
3691 }
3692
3693 int
3694 near_capacity()
3695 {
3696     return calc_capacity(0);
3697 }
3698
3699 int
3700 max_capacity()
3701 {
3702     int wt = inv_weight();
3703
3704     return (wt - (2 * wc));
3705 }
3706
3707 boolean
3708 check_capacity(str)
3709 const char *str;
3710 {
3711     if (near_capacity() >= EXT_ENCUMBER) {
3712         if (str)
3713             pline1(str);
3714         else
3715 /*JP
3716             You_cant("do that while carrying so much stuff.");
3717 */
3718             You("\91ò\8eR\82à\82Ì\82ð\8e\9d\82¿\82·\82¬\82Ä\82¢\82é\82Ì\82Å\81C\82»\82ñ\82È\82±\82Æ\82Í\82Å\82«\82È\82¢\81D");
3719         return 1;
3720     }
3721     return 0;
3722 }
3723
3724 int
3725 inv_cnt(incl_gold)
3726 boolean incl_gold;
3727 {
3728     register struct obj *otmp = invent;
3729     register int ct = 0;
3730
3731     while (otmp) {
3732         if (incl_gold || otmp->invlet != GOLD_SYM)
3733             ct++;
3734         otmp = otmp->nobj;
3735     }
3736     return ct;
3737 }
3738
3739 /* Counts the money in an object chain. */
3740 /* Intended use is for your or some monster's inventory, */
3741 /* now that u.gold/m.gold is gone.*/
3742 /* Counting money in a container might be possible too. */
3743 long
3744 money_cnt(otmp)
3745 struct obj *otmp;
3746 {
3747     while (otmp) {
3748         /* Must change when silver & copper is implemented: */
3749         if (otmp->oclass == COIN_CLASS)
3750             return otmp->quan;
3751         otmp = otmp->nobj;
3752     }
3753     return 0L;
3754 }
3755
3756 /*hack.c*/