OSDN Git Service

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