1 /* NetHack 3.6 hack.c $NHDT-Date: 1446604111 2015/11/04 02:28:31 $ $NHDT-Branch: master $:$NHDT-Revision: 1.155 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* #define DEBUG */ /* uncomment for debugging */
14 STATIC_DCL void NDECL(maybe_wail);
15 STATIC_DCL int NDECL(moverock);
16 STATIC_DCL int FDECL(still_chewing, (XCHAR_P, XCHAR_P));
17 STATIC_DCL void NDECL(dosinkfall);
18 STATIC_DCL boolean FDECL(findtravelpath, (BOOLEAN_P));
19 STATIC_DCL boolean FDECL(trapmove, (int, int, struct trap *));
20 STATIC_DCL void NDECL(switch_terrain);
21 STATIC_DCL struct monst *FDECL(monstinroom, (struct permonst *, int));
22 STATIC_DCL boolean FDECL(doorless_door, (int, int));
23 STATIC_DCL void FDECL(move_update, (BOOLEAN_P));
25 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
27 static anything tmp_anything;
33 tmp_anything = zeroany;
34 tmp_anything.a_uint = ui;
42 tmp_anything = zeroany;
43 tmp_anything.a_long = lng;
51 tmp_anything = zeroany;
52 tmp_anything.a_monst = mtmp;
60 tmp_anything = zeroany;
61 tmp_anything.a_obj = obj;
66 revive_nasty(x, y, msg)
70 register struct obj *otmp, *otmp2;
73 boolean revived = FALSE;
75 for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
76 otmp2 = otmp->nexthere;
77 if (otmp->otyp == CORPSE
78 && (is_rider(&mons[otmp->corpsenm])
79 || otmp->corpsenm == PM_WIZARD_OF_YENDOR)) {
80 /* move any living monster already at that location */
81 if ((mtmp = m_at(x, y)) && enexto(&cc, x, y, mtmp->data))
82 rloc_to(mtmp, cc.x, cc.y);
85 revived = revive_corpse(otmp);
89 /* this location might not be safe, if not, move revived monster */
92 if (mtmp && !goodpos(x, y, mtmp, 0)
93 && enexto(&cc, x, y, mtmp->data)) {
94 rloc_to(mtmp, cc.x, cc.y);
96 /* else impossible? */
105 register xchar rx, ry, sx, sy;
106 register struct obj *otmp;
107 register struct trap *ttmp;
108 register struct monst *mtmp;
110 sx = u.ux + u.dx, sy = u.uy + u.dy; /* boulder starting position */
111 while ((otmp = sobj_at(BOULDER, sx, sy)) != 0) {
112 /* make sure that this boulder is visible as the top object */
113 if (otmp != level.objects[sx][sy])
114 movobj(otmp, sx, sy);
116 rx = u.ux + 2 * u.dx; /* boulder destination position */
117 ry = u.uy + 2 * u.dy;
119 if (Levitation || Is_airlevel(&u.uz)) {
121 feel_location(sx, sy);
123 You("don't have enough leverage to push %s.", the(xname(otmp)));
125 You("
\91Ì
\82ª
\95\82\82¢
\82Ä
\82¢
\82é
\82Ì
\82Å%s
\82ð
\89\9f\82¹
\82È
\82¢
\81D", the(xname(otmp)));
126 /* Give them a chance to climb over it? */
129 if (verysmall(youmonst.data) && !u.usteed) {
131 feel_location(sx, sy);
133 pline("You're too small to push that %s.", xname(otmp));
135 You("
\8f¬
\82³
\82·
\82¬
\82Ä%s
\82ð
\89\9f\82¹
\82È
\82¢
\81D",xname(otmp));
138 if (isok(rx, ry) && !IS_ROCK(levl[rx][ry].typ)
139 && levl[rx][ry].typ != IRONBARS
140 && (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy)
141 || doorless_door(rx, ry)) && !sobj_at(BOULDER, rx, ry)) {
145 /* KMH -- Sokoban doesn't let you push boulders diagonally */
146 if (Sokoban && u.dx && u.dy) {
148 feel_location(sx, sy);
150 pline("%s won't roll diagonally on this %s.",
152 pline("%s
\82Ì
\8fã
\82Å
\82Í%s
\82Í
\8eÎ
\82ß
\82É
\89\9f\82¹
\82È
\82¢
\81D",
153 The(xname(otmp)), surface(sx, sy));
158 if (revive_nasty(rx, ry, "You sense movement on the other side."))
160 if (revive_nasty(rx, ry, "
\94½
\91Î
\91¤
\82É
\93®
\82«
\82ð
\8a´
\82¶
\82½
\81D"))
163 if (mtmp && !noncorporeal(mtmp->data)
165 || !(ttmp && ((ttmp->ttyp == PIT)
166 || (ttmp->ttyp == SPIKED_PIT))))) {
168 feel_location(sx, sy);
169 if (canspotmon(mtmp))
171 pline("There's %s on the other side.", a_monnam(mtmp));
173 pline("
\94½
\91Î
\91¤
\82É%s
\82ª
\82¢
\82é
\81D", a_monnam(mtmp));
176 You_hear("a monster behind %s.", the(xname(otmp)));
178 pline("%s
\82Ì
\94w
\8cã
\82É
\89ö
\95¨
\82Ì
\8bC
\94z
\82ª
\82·
\82é
\81D", the(xname(otmp)));
179 map_invisible(rx, ry);
183 pline("Perhaps that's why %s cannot move it.",
184 u.usteed ? y_monnam(u.usteed) : "you");
186 pline("
\82½
\82Ô
\82ñ
\82±
\82ê
\82ª
\81C
\8aâ
\82ð
\93®
\82©
\82¹
\82È
\82¢
\97\9d\97R
\82¾
\81D");
192 /* if a trap operates on the boulder, don't attempt
193 to move any others at this location; return -1
194 if another boulder is in hero's way, or 0 if he
195 should advance to the vacated boulder position */
196 switch (ttmp->ttyp) {
199 obj_extract_self(otmp);
200 place_object(otmp, rx, ry);
203 pline("KAABLAMM!!! %s %s land mine.",
204 Tobjnam(otmp, "trigger"),
205 ttmp->madeby_u ? "your" : "a");
207 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",
209 ttmp->madeby_u ? "
\82 \82È
\82½
\82Ì
\8ed
\8a|
\82¯
\82½" : "");
211 blow_up_landmine(ttmp);
212 /* if the boulder remains, it should fill the pit */
213 fill_pit(u.ux, u.uy);
216 return sobj_at(BOULDER, sx, sy) ? -1 : 0;
221 obj_extract_self(otmp);
222 /* vision kludge to get messages right;
223 the pit will temporarily be seen even
224 if this is one among multiple boulders */
226 viz_array[ry][rx] |= IN_SIGHT;
228 if (!flooreffects(otmp, rx, ry, "fall")) {
230 if (!flooreffects(otmp, rx, ry, "
\97\8e\82¿
\82é")) {
231 place_object(otmp, rx, ry);
235 return sobj_at(BOULDER, sx, sy) ? -1 : 0;
240 pline("Kerplunk! You no longer feel %s.",
242 pline("
\83h
\83T
\83b
\81I
\82 \82È
\82½
\82Í
\82à
\82¤%s
\82ð
\8a´
\82¶
\82ç
\82ê
\82È
\82¢
\81D",
246 pline("%s%s and %s a %s in the %s!",
247 Tobjnam(otmp, (ttmp->ttyp == TRAPDOOR)
250 (ttmp->ttyp == TRAPDOOR) ? "" : " into",
251 otense(otmp, "plug"),
252 (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole",
255 pline("%s
\82Í
\97\8e\82¿
\82Ä%s
\82Ì%s
\82ð
\96\84\82ß
\82½
\81I",
258 (ttmp->ttyp == TRAPDOOR) ? "
\97\8e\82µ
\94à" : "
\8c\8a");
263 levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
264 levl[rx][ry].candig = 1;
267 return sobj_at(BOULDER, sx, sy) ? -1 : 0;
270 int newlev = 0; /* lint suppression */
273 if (ttmp->ttyp == LEVEL_TELEP) {
274 newlev = random_teleport_level();
275 if (newlev == depth(&u.uz) || In_endgame(&u.uz))
276 /* trap didn't work; skip "disappears" message */
281 pline("%s pushes %s and suddenly it disappears!",
283 pline("%s
\82ª%s
\82ð
\89\9f\82·
\82Æ
\81C
\93Ë
\91R
\82»
\82ê
\82Í
\8fÁ
\96Å
\82µ
\82½
\81I",
284 upstart(y_monnam(u.usteed)), the(xname(otmp)));
287 You("push %s and suddenly it disappears!",
289 pline("
\82 \82È
\82½
\82ª%s
\82ð
\89\9f\82·
\82Æ
\81C
\93Ë
\91R
\82»
\82ê
\82Í
\8fÁ
\96Å
\82µ
\82½
\81I",
291 if (ttmp->ttyp == TELEP_TRAP) {
294 obj_extract_self(otmp);
295 add_to_migration(otmp);
296 get_level(&dest, newlev);
297 otmp->ox = dest.dnum;
298 otmp->oy = dest.dlevel;
299 otmp->owornmask = (long) MIGR_RANDOM;
302 return sobj_at(BOULDER, sx, sy) ? -1 : 0;
305 break; /* boulder not affected by this trap */
309 if (closed_door(rx, ry))
311 if (boulder_hits_pool(otmp, rx, ry, TRUE))
314 * Re-link at top of fobj chain so that pile order is preserved
315 * when level is restored.
319 place_object(otmp, otmp->ox, otmp->oy);
323 #ifdef LINT /* static long lastmovetime; */
327 /* note: reset to zero after save/restore cycle */
328 static NEARDATA long lastmovetime;
332 if (moves > lastmovetime + 2 || moves < lastmovetime)
334 pline("With %s effort you move %s.",
335 throws_rocks(youmonst.data) ? "little"
339 pline("%s
\97Í
\82ð
\82±
\82ß
\82Ä%s
\82ð
\89\9f\82µ
\82½
\81D",
340 throws_rocks(youmonst.data) ? "
\8f
\82µ" : "
\82©
\82È
\82è",
343 exercise(A_STR, TRUE);
346 pline("%s moves %s.", upstart(y_monnam(u.usteed)),
349 pline("%s
\82Í%s
\82ð
\93®
\82©
\82µ
\82½
\81D", upstart(y_monnam(u.usteed)),
352 lastmovetime = moves;
355 /* Move the boulder *after* the message. */
356 if (glyph_is_invisible(levl[rx][ry].glyph))
357 unmap_object(rx, ry);
358 movobj(otmp, rx, ry); /* does newsym(rx,ry) */
360 feel_location(rx, ry);
361 feel_location(sx, sy);
369 pline("%s tries to move %s, but cannot.",
370 upstart(y_monnam(u.usteed)), the(xname(otmp)));
372 pline("%s
\82Í%s
\82ð
\93®
\82©
\82»
\82¤
\82Æ
\82µ
\82½
\82ª
\8fo
\97\88\82È
\82©
\82Á
\82½
\81D",
373 upstart(y_monnam(u.usteed)), the(xname(otmp)));
377 You("try to move %s, but in vain.", the(xname(otmp)));
379 You("%s
\82ð
\93®
\82©
\82»
\82¤
\82Æ
\82µ
\82½
\82ª
\81C
\82¾
\82ß
\82¾
\82Á
\82½
\81D", the(xname(otmp)));
381 feel_location(sx, sy);
383 if (throws_rocks(youmonst.data)) {
384 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
386 You("aren't skilled enough to %s %s from %s.",
387 (flags.pickup && !Sokoban) ? "pick up" : "push aside",
388 the(xname(otmp)), y_monnam(u.usteed));
390 You("%s
\82É%s
\82ð%s
\82é
\82Ù
\82Ç
\8bZ
\97Ê
\82ª
\82È
\82¢
\81D",
393 (flags.pickup && !Sokoban) ? "
\8fE
\82í
\82¹" : "
\89\9f\82³
\82¹");
397 pline("However, you can easily %s.",
398 (flags.pickup && !Sokoban) ? "pick it up"
401 pline("
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\8aÈ
\92P
\82É
\82»
\82ê
\82ð%s
\81D",
402 (flags.pickup && !Sokoban)
403 ? "
\8fE
\82¦
\82½" : "
\95Ê
\82Ì
\95û
\82É
\89\9f\82¹
\82½");
412 && (((!invent || inv_weight() <= -850)
413 && (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][sy].typ)
414 && IS_ROCK(levl[sx][u.uy].typ))))
415 || verysmall(youmonst.data))) {
418 "However, you can squeeze yourself into a small opening.");
420 "
\82µ
\82©
\82µ
\81C
\82 \82È
\82½
\82Í
\8f¬
\82³
\82¢
\8c\84\8aÔ
\82É
\82±
\82¶
\93ü
\82Á
\82½
\81D");
433 * Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE
440 struct rm *lev = &levl[x][y];
441 struct obj *boulder = sobj_at(BOULDER, x, y);
442 const char *digtxt = (char *) 0, *dmgtxt = (char *) 0;
444 if (context.digging.down) /* not continuing previous dig (w/ pick-axe) */
445 (void) memset((genericptr_t) &context.digging, 0,
446 sizeof(struct dig_info));
448 if (!boulder && IS_ROCK(lev->typ) && !may_dig(x, y)) {
450 You("hurt your teeth on the %s.",
451 (lev->typ == IRONBARS)
457 You("%s
\82Å
\8e\95\82ð
\92É
\82ß
\82½
\81D",
458 (lev->typ == IRONBARS)
466 } else if (context.digging.pos.x != x || context.digging.pos.y != y
467 || !on_level(&context.digging.level, &u.uz)) {
468 context.digging.down = FALSE;
469 context.digging.chew = TRUE;
470 context.digging.warned = FALSE;
471 context.digging.pos.x = x;
472 context.digging.pos.y = y;
473 assign_level(&context.digging.level, &u.uz);
474 /* solid rock takes more work & time to dig through */
475 context.digging.effort =
476 (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc;
478 You("start chewing %s %s.",
479 (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS)
488 : lev->typ == IRONBARS
492 You("%s%s
\82Í
\82¶
\82ß
\82½
\81D",
499 : lev->typ == IRONBARS
502 (boulder || IS_TREE(lev->typ) || lev->typ == IRONBARS)
504 : "
\82É
\8c\8a\82ð
\82 \82¯");
506 watch_dig((struct monst *) 0, x, y, FALSE);
508 } else if ((context.digging.effort += (30 + u.udaminc)) <= 100) {
511 You("%s chewing on the %s.",
512 context.digging.chew ? "continue" : "begin",
519 : (lev->typ == IRONBARS)
523 You("%s
\82ð
\8a\9a\82Ý%s
\81D",
530 : lev->typ == IRONBARS
533 context.digging.chew ? "
\91±
\82¯
\82½" : "
\82Í
\82¶
\82ß
\82½");
535 context.digging.chew = TRUE;
536 watch_dig((struct monst *) 0, x, y, FALSE);
540 /* Okay, you've chewed through something */
542 u.uhunger += rnd(20);
545 delobj(boulder); /* boulder goes bye-bye */
547 You("eat the boulder."); /* yum */
549 You("
\8aâ
\82ð
\90H
\82×
\82½
\81D"); /* yum */
553 * The location could still block because of
554 * 1. More than one boulder
555 * 2. Boulder stuck in a wall/stone/door.
557 * [perhaps use does_block() below (from vision.c)]
559 if (IS_ROCK(lev->typ) || closed_door(x, y)
560 || sobj_at(BOULDER, x, y)) {
561 block_point(x, y); /* delobj will unblock the point */
562 /* reset dig state */
563 (void) memset((genericptr_t) &context.digging, 0,
564 sizeof(struct dig_info));
568 } else if (IS_WALL(lev->typ)) {
569 if (*in_rooms(x, y, SHOPBASE)) {
570 add_damage(x, y, 10L * ACURRSTR);
574 dmgtxt = "
\8f\9d\82Â
\82¯
\82é";
577 digtxt = "chew a hole in the wall.";
579 digtxt = "
\95Ç
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D";
580 if (level.flags.is_maze_lev) {
582 } else if (level.flags.is_cavernous_lev && !in_town(x, y)) {
586 lev->doormask = D_NODOOR;
588 } else if (IS_TREE(lev->typ)) {
590 digtxt = "chew through the tree.";
592 digtxt = "
\96Ø
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D";
594 } else if (lev->typ == IRONBARS) {
596 digtxt = "eat through the bars.";
598 digtxt = "
\93S
\82Ì
\96_
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D";
600 } else if (lev->typ == SDOOR) {
601 if (lev->doormask & D_TRAPPED) {
602 lev->doormask = D_NODOOR;
604 b_trapped("secret door", 0);
606 b_trapped("
\94é
\96§
\82Ì
\94à", 0);
609 digtxt = "chew through the secret door.";
611 digtxt = "
\94é
\96§
\82Ì
\94à
\82ð
\8a\9a\82Ý
\8dÓ
\82¢
\82½
\81D";
612 lev->doormask = D_BROKEN;
616 } else if (IS_DOOR(lev->typ)) {
617 if (*in_rooms(x, y, SHOPBASE)) {
618 add_damage(x, y, 400L);
624 if (lev->doormask & D_TRAPPED) {
625 lev->doormask = D_NODOOR;
627 b_trapped("door", 0);
629 b_trapped("
\94à", 0);
632 digtxt = "chew through the door.";
634 digtxt = "
\94à
\82ð
\8dÓ
\82¢
\82½
\81D";
635 lev->doormask = D_BROKEN;
638 } else { /* STONE or SCORR */
640 digtxt = "chew a passage through the rock.";
642 digtxt = "
\8aâ
\82ð
\8a\9a\82Ý
\8dÓ
\82¢
\82Ä
\92Ê
\82è
\94²
\82¯
\82½
\81D";
646 unblock_point(x, y); /* vision */
649 You1(digtxt); /* after newsym */
651 pay_for_damage(dmgtxt, FALSE);
652 (void) memset((genericptr_t) &context.digging, 0,
653 sizeof(struct dig_info));
659 register struct obj *obj;
660 register xchar ox, oy;
662 /* optimize by leaving on the fobj chain? */
664 newsym(obj->ox, obj->oy);
665 place_object(obj, ox, oy);
670 static NEARDATA const char fell_on_sink[] = "fell onto a sink";
672 static NEARDATA const char fell_on_sink[] = "
\97¬
\82µ
\91ä
\82É
\97\8e\82¿
\82Ä";
677 register struct obj *obj;
679 boolean lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS),
680 innate_lev = ((HLevitation & (FROMOUTSIDE | FROMFORM)) != 0L),
681 ufall = (!innate_lev && !(HFlying || EFlying)); /* BFlying */
685 You(innate_lev ? "wobble unsteadily for a moment."
687 You(innate_lev ? "
\82¿
\82å
\82Á
\82Æ
\82Ó
\82ç
\82Â
\82¢
\82½
\81D"
689 : "gain control of your flight.");
691 : "
\94ò
\8ds
\92\86\82Ì
\90§
\8cä
\82ð
\8eæ
\82è
\82à
\82Ç
\82µ
\82½
\81D");
693 long save_ELev = ELevitation, save_HLev = HLevitation;
695 /* fake removal of levitation in advance so that final
696 disclosure will be right in case this turns out to
697 be fatal; fortunately the fact that rings and boots
698 are really still worn has no effect on bones data */
699 ELevitation = HLevitation = 0L;
701 You("crash to the floor!");
703 You("
\8f°
\82É
\92@
\82«
\82Â
\82¯
\82ç
\82ê
\82½
\81I");
704 dmg = rn1(8, 25 - (int) ACURR(A_CON));
705 losehp(Maybe_Half_Phys(dmg), fell_on_sink, NO_KILLER_PREFIX);
706 exercise(A_DEX, FALSE);
708 selftouch("Falling, you");
710 selftouch("
\97\8e\82¿
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í");
711 for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere)
712 if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) {
714 You("fell on %s.", doname(obj));
716 You("%s
\82Ì
\8fã
\82É
\97\8e\82¿
\82½
\81D",doname(obj));
718 losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink,
721 losehp(Maybe_Half_Phys(rnd(3)), fell_on_sink,
724 exercise(A_CON, FALSE);
726 ELevitation = save_ELev;
727 HLevitation = save_HLev;
731 * Interrupt multi-turn putting on/taking off of armor (in which
732 * case we reached the sink due to being teleported while busy;
733 * in 3.4.3, Boots_on()/Boots_off() [called via (*aftermv)() when
734 * 'multi' reaches 0] triggered a crash if we were donning/doffing
735 * levitation boots [because the Boots_off() below causes 'uarmf'
736 * to be null by the time 'aftermv' gets called]).
738 * Interrupt donning/doffing if we fall onto the sink, or if the
739 * code below is going to remove levitation boots even when we
740 * haven't fallen (innate floating or flying becoming unblocked).
742 if (ufall || lev_boots) {
743 (void) stop_donning(lev_boots ? uarmf : (struct obj *) 0);
744 /* recalculate in case uarmf just got set to null */
745 lev_boots = (uarmf && uarmf->otyp == LEVITATION_BOOTS);
748 /* remove worn levitation items */
749 ELevitation &= ~W_ARTI;
750 HLevitation &= ~(I_SPECIAL | TIMEOUT);
752 if (uleft && uleft->otyp == RIN_LEVITATION) {
757 if (uright && uright->otyp == RIN_LEVITATION) {
768 /* probably moot; we're either still levitating or went
769 through float_down(), but make sure BFlying is up to date */
773 /* intended to be called only on ROCKs or TREEs */
778 struct rm *lev = &levl[x][y];
780 return (boolean) !((IS_STWALL(lev->typ) || IS_TREE(lev->typ))
781 && (lev->wall_info & W_NONDIGGABLE));
788 return (boolean) !(IS_STWALL(levl[x][y].typ)
789 && (levl[x][y].wall_info & W_NONPASSWALL));
794 struct permonst *mdat;
797 return (boolean) ((Sokoban && sobj_at(BOULDER, x, y))
798 || (IS_ROCK(levl[x][y].typ)
799 && (!tunnels(mdat) || needspick(mdat)
801 && !(passes_walls(mdat) && may_passwall(x, y))));
804 /* caller has already decided that it's a tight diagonal; check whether a
805 monster--who might be the hero--can fit through, and if not then return
806 the reason why: 1: can't fit, 2: possessions won't fit, 3: sokoban */
807 int /* returns 0 if we can squeeze through */
808 cant_squeeze_thru(mon)
812 struct permonst *ptr = mon->data;
816 && !(amorphous(ptr) || is_whirly(ptr) || noncorporeal(ptr)
817 || slithy(ptr) || can_fog(mon)))
820 /* lugging too much junk? */
822 (mon == &youmonst) ? inv_weight() + weight_cap() : curr_mon_load(mon);
826 /* Sokoban restriction applies to hero only */
827 if (mon == &youmonst && Sokoban)
830 /* can squeeze through */
838 return (boolean) (Invocation_lev(&u.uz)
839 && x == inv_pos.x && y == inv_pos.y);
842 /* return TRUE if (dx,dy) is an OK place to move
843 * mode is one of DO_MOVE, TEST_MOVE or TEST_TRAV
846 test_move(ux, uy, dx, dy, mode)
852 register struct rm *tmpr = &levl[x][y];
853 register struct rm *ust;
855 context.door_opened = FALSE;
857 * Check for physical obstacles. First, the place we are going.
859 if (IS_ROCK(tmpr->typ) || tmpr->typ == IRONBARS) {
860 if (Blind && mode == DO_MOVE)
862 if (Passes_walls && may_passwall(x, y)) {
864 } else if (tmpr->typ == IRONBARS) {
865 if ((dmgtype(youmonst.data, AD_RUST)
866 || dmgtype(youmonst.data, AD_CORR)) && mode == DO_MOVE
867 && still_chewing(x, y)) {
870 if (!(Passes_walls || passes_bars(youmonst.data))) {
871 if (iflags.mention_walls)
873 You("cannot pass through the bars.");
875 You("
\93S
\82Ì
\96_
\82ð
\92Ê
\82è
\94²
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
878 } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
880 if (mode == DO_MOVE && still_chewing(x, y))
882 } else if (flags.autodig && !context.run && !context.nopick && uwep
884 /* MRKR: Automatic digging when wielding the appropriate tool */
886 (void) use_pick_axe2(uwep);
889 if (mode == DO_MOVE) {
890 if (Is_stronghold(&u.uz) && is_db_wall(x, y))
892 pline_The("drawbridge is up!");
894 pline("
\92µ
\82Ë
\8b´
\82Í
\8fã
\82Á
\82Ä
\82¢
\82é
\81I");
895 /* sokoban restriction stays even after puzzle is solved */
896 else if (Passes_walls && !may_passwall(x, y)
897 && In_sokoban(&u.uz))
899 pline_The("Sokoban walls resist your ability.");
901 pline_The("
\91q
\8cÉ
\94Ô
\82Ì
\95Ç
\82Í
\82 \82È
\82½
\82Ì
\94\
\97Í
\82É
\92ï
\8dR
\82µ
\82½
\81D");
902 else if (iflags.mention_walls)
904 pline("It's a wall.");
906 pline("
\82±
\82ê
\82Í
\95Ç
\82¾
\81D");
910 } else if (IS_DOOR(tmpr->typ)) {
911 if (closed_door(x, y)) {
912 if (Blind && mode == DO_MOVE)
916 else if (can_ooze(&youmonst)) {
919 You("ooze under the door.");
921 You("
\83h
\83A
\82Ì
\89º
\82©
\82ç
\82É
\82¶
\82Ý
\8fo
\82½
\81D");
922 } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
924 if (mode == DO_MOVE && still_chewing(x, y))
927 if (mode == DO_MOVE) {
928 if (amorphous(youmonst.data))
931 "try to ooze under the door, but can't squeeze your possessions through.");
933 "
\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");
934 if (flags.autoopen && !context.run && !Confusion
935 && !Stunned && !Fumbling) {
936 context.door_opened = context.move =
938 } else if (x == ux || y == uy) {
939 if (Blind || Stunned || ACURR(A_DEX) < 10
943 You_cant("lead %s through that closed door.",
945 You_cant("%s
\82É
\95Â
\82Ü
\82Á
\82½
\94à
\82ð
\92Ê
\89ß
\82³
\82¹
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
949 pline("Ouch! You bump into a door.");
951 pline("
\82¢
\82Ä
\82Á
\81I
\93ª
\82ð
\94à
\82É
\82Ô
\82Â
\82¯
\82½
\81D");
952 exercise(A_DEX, FALSE);
956 pline("That door is closed.");
958 pline("
\94à
\82Í
\95Â
\82Ü
\82Á
\82Ä
\82¢
\82é
\81D");
960 } else if (mode == TEST_TRAV)
966 if (dx && dy && !Passes_walls
967 && (!doorless_door(x, y) || block_door(x, y))) {
968 /* Diagonal moves into a door are not allowed. */
969 if (Blind && mode == DO_MOVE)
975 if (dx && dy && bad_rock(youmonst.data, ux, y)
976 && bad_rock(youmonst.data, x, uy)) {
977 /* Move at a diagonal. */
978 switch (cant_squeeze_thru(&youmonst)) {
982 You("cannot pass that way.");
984 You("
\92Ê
\82è
\82Ê
\82¯
\82Å
\82«
\82È
\82¢
\81D");
989 You("are carrying too much to get through.");
991 pline("
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\92Ê
\82è
\82Ê
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
996 Your("body is too large to fit through.");
998 Your("
\91Ì
\82ª
\91å
\82«
\82·
\82¬
\82Ä
\92Ê
\82è
\82Ê
\82¯
\82ç
\82ê
\82È
\82¢
\81D");
1001 break; /* can squeeze through */
1003 } else if (dx && dy && worm_cross(ux, uy, x, y)) {
1004 /* consecutive long worm segments are at <ux,y> and <x,uy> */
1005 if (mode == DO_MOVE)
1007 pline("%s is in your way.", Monnam(m_at(ux, y)));
1009 pline("
\93¹
\82Ì
\93r
\92\86\82É%s
\82ª
\82¢
\82é
\81D", Monnam(m_at(ux, y)));
1012 /* Pick travel path that does not require crossing a trap.
1013 * Avoid water and lava using the usual running rules.
1014 * (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
1015 if (context.run == 8 && mode != DO_MOVE && (x != u.ux || y != u.uy)) {
1016 struct trap *t = t_at(x, y);
1019 || (!Levitation && !Flying && !is_clinger(youmonst.data)
1020 && is_pool_or_lava(x, y) && levl[x][y].seenv))
1024 ust = &levl[ux][uy];
1026 /* Now see if other things block our way . . */
1027 if (dx && dy && !Passes_walls && IS_DOOR(ust->typ)
1028 && (!doorless_door(ux, uy) || block_entry(x, y))) {
1029 /* Can't move at a diagonal out of a doorway with door. */
1033 if (sobj_at(BOULDER, x, y) && (Sokoban || !Passes_walls)) {
1034 if (!(Blind || Hallucination) && (context.run >= 2)
1035 && mode != TEST_TRAV)
1037 if (mode == DO_MOVE) {
1038 /* tunneling monsters will chew before pushing */
1039 if (tunnels(youmonst.data) && !needspick(youmonst.data)
1041 if (still_chewing(x, y))
1043 } else if (moverock() < 0)
1045 } else if (mode == TEST_TRAV) {
1048 /* don't pick two boulders in a row, unless there's a way thru */
1049 if (sobj_at(BOULDER, ux, uy) && !Sokoban) {
1051 && !(tunnels(youmonst.data) && !needspick(youmonst.data))
1052 && !carrying(PICK_AXE) && !carrying(DWARVISH_MATTOCK)
1053 && !((obj = carrying(WAN_DIGGING))
1054 && !objects[obj->otyp].oc_name_known))
1058 /* assume you'll be able to push it when you get there... */
1061 /* OK, it is a legal place to move. */
1066 static boolean trav_debug = FALSE;
1068 /* in this case, toggle display of travel debug info */
1069 int wiz_debug_cmd_traveldisplay()
1071 trav_debug = !trav_debug;
1077 * Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
1078 * A shortest path is returned. If guess is TRUE, consider various
1079 * inaccessible locations as valid intermediate path points.
1080 * Returns TRUE if a path was found.
1083 findtravelpath(guess)
1086 /* if travel to adjacent, reachable location, use normal movement rules */
1087 if (!guess && context.travel1 && distmin(u.ux, u.uy, u.tx, u.ty) == 1
1088 && !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) {
1090 if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) {
1094 iflags.travelcc.x = iflags.travelcc.y = -1;
1099 if (u.tx != u.ux || u.ty != u.uy) {
1100 xchar travel[COLNO][ROWNO];
1101 xchar travelstepx[2][COLNO * ROWNO];
1102 xchar travelstepy[2][COLNO * ROWNO];
1103 xchar tx, ty, ux, uy;
1104 int n = 1; /* max offset in travelsteps */
1105 int set = 0; /* two sets current and previous */
1106 int radius = 1; /* search radius */
1109 /* If guessing, first find an "obvious" goal location. The obvious
1110 * goal is the position the player knows of, or might figure out
1111 * (couldsee) that is closest to the target on a straight path.
1126 (void) memset((genericptr_t) travel, 0, sizeof(travel));
1127 travelstepx[0][0] = tx;
1128 travelstepy[0][0] = ty;
1133 for (i = 0; i < n; i++) {
1135 int x = travelstepx[set][i];
1136 int y = travelstepy[set][i];
1137 static int ordered[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
1138 /* no diagonal movement for grid bugs */
1139 int dirmax = NODIAG(u.umonnum) ? 4 : 8;
1141 for (dir = 0; dir < dirmax; ++dir) {
1142 int nx = x + xdir[ordered[dir]];
1143 int ny = y + ydir[ordered[dir]];
1147 if ((!Passes_walls && !can_ooze(&youmonst)
1148 && closed_door(x, y)) || sobj_at(BOULDER, x, y)) {
1149 /* closed doors and boulders usually
1150 * cause a delay, so prefer another path */
1151 if (travel[x][y] > radius - 3) {
1152 travelstepx[1 - set][nn] = x;
1153 travelstepy[1 - set][nn] = y;
1154 /* don't change travel matrix! */
1159 if (test_move(x, y, nx - x, ny - y, TEST_TRAV)
1160 && (levl[nx][ny].seenv
1161 || (!Blind && couldsee(nx, ny)))) {
1162 if (nx == ux && ny == uy) {
1166 if (x == u.tx && y == u.ty) {
1168 /* reset run so domove run checks work */
1170 iflags.travelcc.x = iflags.travelcc.y =
1175 } else if (!travel[nx][ny]) {
1176 travelstepx[1 - set][nn] = nx;
1177 travelstepy[1 - set][nn] = ny;
1178 travel[nx][ny] = radius;
1187 /* Use of warning glyph is arbitrary. It stands out. */
1188 tmp_at(DISP_ALL, warning_to_glyph(1));
1189 for (i = 0; i < nn; ++i) {
1190 tmp_at(travelstepx[1 - set][i], travelstepy[1 - set][i]);
1193 if (flags.runmode == RUN_CRAWL) {
1197 tmp_at(DISP_END, 0);
1206 /* if guessing, find best location in travel matrix and go there */
1208 int px = tx, py = ty; /* pick location */
1209 int dist, nxtdist, d2, nd2;
1211 dist = distmin(ux, uy, tx, ty);
1212 d2 = dist2(ux, uy, tx, ty);
1213 for (tx = 1; tx < COLNO; ++tx)
1214 for (ty = 0; ty < ROWNO; ++ty)
1215 if (travel[tx][ty]) {
1216 nxtdist = distmin(ux, uy, tx, ty);
1217 if (nxtdist == dist && couldsee(tx, ty)) {
1218 nd2 = dist2(ux, uy, tx, ty);
1220 /* prefer non-zigzag path */
1225 } else if (nxtdist < dist && couldsee(tx, ty)) {
1229 d2 = dist2(ux, uy, tx, ty);
1233 if (px == u.ux && py == u.uy) {
1234 /* no guesses, just go in the general direction */
1235 u.dx = sgn(u.tx - u.ux);
1236 u.dy = sgn(u.ty - u.uy);
1237 if (test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE))
1243 /* Use of warning glyph is arbitrary. It stands out. */
1244 tmp_at(DISP_ALL, warning_to_glyph(2));
1247 if (flags.runmode == RUN_CRAWL) {
1253 tmp_at(DISP_END, 0);
1275 /* try to escape being stuck in a trapped state by walking out of it;
1276 return true iff moving should continue to intended destination
1277 (all failures and most successful escapes leave hero at original spot) */
1279 trapmove(x, y, desttrap)
1280 int x, y; /* targetted destination, <u.ux+u.dx,u.uy+u.dy> */
1281 struct trap *desttrap; /* nonnull if another trap at <x,y> */
1284 const char *predicament, *culprit;
1285 char *steedname = !u.usteed ? (char *) 0 : y_monnam(u.usteed);
1288 return TRUE; /* sanity check */
1290 switch (u.utraptype) {
1292 if (flags.verbose) {
1294 predicament = "caught in a bear trap";
1296 predicament = "
\8cF
\82Ìã©
\82É
\82Â
\82©
\82Ü
\82Á
\82½";
1299 Norep("%s is %s.", upstart(steedname), predicament);
1301 Norep("%s
\82Í%s
\81D", upstart(steedname), predicament);
1304 Norep("You are %s.", predicament);
1306 Norep("
\82 \82È
\82½
\82Í%s
\81D", predicament);
1308 /* [why does diagonal movement give quickest escape?] */
1309 if ((u.dx && u.dy) || !rn2(5))
1313 if (desttrap && desttrap->tseen
1314 && (desttrap->ttyp == PIT || desttrap->ttyp == SPIKED_PIT))
1315 return TRUE; /* move into adjacent pit */
1316 /* try to escape; position stays same regardless of success */
1320 if (uwep && uwep->oartifact == ART_STING) {
1323 pline("Sting cuts through the web!");
1325 pline("
\83X
\83e
\83B
\83\93\83O
\82Í
\82
\82à
\82Ì
\91\83\82ð
\90Ø
\82è
\82³
\82¢
\82½
\81I");
1326 break; /* escape trap but don't move */
1329 if (flags.verbose) {
1331 predicament = "stuck to the web";
1333 predicament = "
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82½";
1336 Norep("%s is %s.", upstart(steedname), predicament);
1338 Norep("%s
\82Í%s
\81D", upstart(steedname), predicament);
1341 Norep("You are %s.", predicament);
1343 Norep("
\82 \82È
\82½
\82Í%s
\81D", predicament);
1348 pline("%s breaks out of the web.", upstart(steedname));
1350 pline("%s
\82Í
\82
\82à
\82Ì
\91\83\82ð
\89ó
\82µ
\82½
\81D", upstart(steedname));
1353 You("disentangle yourself.");
1355 You("
\8e©
\95ª
\82Å
\82Ù
\82Ç
\82¢
\82½
\81D");
1359 if (flags.verbose) {
1361 predicament = "stuck in the lava";
1363 predicament = "
\97n
\8aâ
\82É
\82Í
\82Ü
\82Á
\82½";
1366 Norep("%s is %s.", upstart(steedname), predicament);
1368 Norep("%s
\82Í%s
\81D", upstart(steedname), predicament);
1371 Norep("You are %s.", predicament);
1373 Norep("
\82 \82È
\82½
\82Í%s
\81D", predicament);
1375 if (!is_lava(x, y)) {
1377 if ((u.utrap & 0xff) == 0) {
1381 You("lead %s to the edge of the lava.", steedname);
1383 You("%s
\82ð
\97n
\8aâ
\82Ì
\92[
\82Ü
\82Å
\93±
\82¢
\82½
\81D", steedname);
1386 You("pull yourself to the edge of the lava.");
1388 You("
\97n
\8aâ
\82Ì
\92[
\82Ü
\82Å
\82©
\82ë
\82¤
\82¶
\82Ä
\81C
\82½
\82Ç
\82è
\82Â
\82¢
\82½
\81D");
1395 anchored = (u.utraptype == TT_BURIEDBALL);
1399 cc.x = u.ux, cc.y = u.uy;
1400 /* can move normally within radius 1 of buried ball */
1401 if (buried_ball(&cc) && dist2(x, y, cc.x, cc.y) <= 2) {
1402 /* ugly hack: we need to issue some message here
1403 in case "you are chained to the buried ball"
1404 was the most recent message given, otherwise
1405 our next attempt to move out of tether range
1406 after this successful move would have its
1407 can't-do-that message suppressed by Norep */
1410 Norep("You move within the chain's reach.");
1412 Norep("
\8d½
\82ª
\93Í
\82
\94Í
\88Í
\82É
\88Ú
\93®
\82Å
\82«
\82é
\81D");
1417 if (flags.verbose) {
1420 predicament = "chained to the";
1421 culprit = "buried ball";
1423 predicament = "
\82Æ
\82Â
\82È
\82ª
\82Á
\82Ä
\82¢
\82é";
1424 culprit = "
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\8b\85";
1428 predicament = "stuck in the";
1429 culprit = surface(u.ux, u.uy);
1431 predicament = "
\82É
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é";
1432 culprit = surface(u.ux, u.uy);
1438 Norep("You and %s are %s %s.", steedname, predicament,
1441 Norep("
\82 \82È
\82½
\82Æ%s
\82Í%s%s
\81D", steedname, culprit,
1446 Norep("%s is %s %s.", upstart(steedname), predicament,
1449 Norep("%s
\82Í%s%s
\81D", steedname, culprit,
1454 Norep("You are %s %s.", predicament, culprit);
1456 Norep("
\82 \82È
\82½
\82Í%s
\82É%s
\81D", culprit, predicament);
1461 pline("%s finally %s free.", upstart(steedname),
1462 !anchored ? "lurches" : "wrenches the ball");
1464 pline("%s
\82Í%s
\82â
\82Á
\82Æ
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D", upstart(steedname),
1465 !anchored ? "
\82à
\82ª
\82¢
\82Ä" : "
\93S
\8b\85\82ð
\82à
\82¬
\8eæ
\82Á
\82Ä");
1469 You("finally %s free.",
1470 !anchored ? "wriggle" : "wrench the ball");
1472 You("%s
\82â
\82Á
\82Æ
\8e©
\97R
\82É
\82È
\82Á
\82½
\81D",
1473 !anchored ? "
\82à
\82ª
\82¢
\82Ä" : "
\93S
\8b\85\82ð
\82à
\82¬
\8eæ
\82Á
\82Ä");
1476 buried_ball_to_punishment();
1480 impossible("trapmove: stuck in unknown trap? (%d)",
1490 if (!youmonst.data->mmove) {
1492 You("are rooted %s.",
1493 Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
1497 You("
\82»
\82Ì
\8fê
\82É
\97§
\82¿
\82·
\82
\82ñ
\82¾
\81D");
1508 register struct monst *mtmp;
1509 register struct rm *tmpr;
1510 register xchar x, y;
1511 struct trap *trap = NULL;
1514 xchar chainx = 0, chainy = 0,
1515 ballx = 0, bally = 0; /* ball&chain new positions */
1516 int bc_control = 0; /* control for ball&chain */
1517 boolean cause_delay = FALSE; /* dragging ball will skip a move */
1519 u_wipe_engr(rnd(5));
1521 if (context.travel) {
1522 if (!findtravelpath(FALSE))
1523 (void) findtravelpath(TRUE);
1524 context.travel1 = 0;
1527 if (((wtcap = near_capacity()) >= OVERLOADED
1528 || (wtcap > SLT_ENCUMBER
1529 && (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
1530 : (u.uhp < 10 && u.uhp != u.uhpmax))))
1531 && !Is_airlevel(&u.uz)) {
1532 if (wtcap < OVERLOADED) {
1534 You("don't have enough stamina to move.");
1536 You("
\82Ö
\82Æ
\82Ö
\82Æ
\82Å
\93®
\82¯
\82È
\82¢
\81D");
1537 exercise(A_CON, FALSE);
1540 You("collapse under your load.");
1542 pline("
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\93|
\82ê
\82½
\81D");
1548 u.ux = x = u.ustuck->mx;
1549 u.uy = y = u.ustuck->my;
1552 if (Is_airlevel(&u.uz) && rn2(4) && !Levitation && !Flying) {
1556 You("tumble in place.");
1558 You("
\82»
\82Ì
\8fê
\82Å
\93|
\82ê
\82½
\81D");
1559 exercise(A_DEX, FALSE);
1563 You_cant("control your movements very well.");
1565 You("
\82¤
\82Ü
\82
\95à
\82¯
\82È
\82¢
\81D");
1569 pline("It's hard to walk in thin air.");
1571 pline("
\8bó
\92\86\82ð
\95à
\82
\82Ì
\82Í
\93ï
\82µ
\82¢
\81D");
1572 exercise(A_DEX, TRUE);
1578 /* check slippery ice */
1579 on_ice = !Levitation && is_ice(u.ux, u.uy);
1581 static int skates = 0;
1583 skates = find_skates();
1584 if ((uarmf && uarmf->otyp == skates) || resists_cold(&youmonst)
1585 || Flying || is_floater(youmonst.data)
1586 || is_clinger(youmonst.data) || is_whirly(youmonst.data))
1588 else if (!rn2(Cold_resistance ? 3 : 2)) {
1589 HFumbling |= FROMOUTSIDE;
1590 HFumbling &= ~TIMEOUT;
1591 HFumbling += 1; /* slip on next move */
1594 if (!on_ice && (HFumbling & FROMOUTSIDE))
1595 HFumbling &= ~FROMOUTSIDE;
1599 if (Stunned || (Confusion && !rn2(5))) {
1600 register int tries = 0;
1610 } while (!isok(x, y) || bad_rock(youmonst.data, x, y));
1612 /* turbulence might alter your actual destination */
1615 if (!u.dx && !u.dy) {
1626 if (((trap = t_at(x, y)) && trap->tseen)
1627 || (Blind && !Levitation && !Flying && !is_clinger(youmonst.data)
1628 && is_pool_or_lava(x, y) && levl[x][y].seenv)) {
1629 if (context.run >= 2) {
1637 if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
1638 if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
1639 /* perhaps it fled (or was teleported or ... ) */
1641 } else if (sticks(youmonst.data)) {
1642 /* When polymorphed into a sticking monster,
1643 * u.ustuck means it's stuck to you, not you to it.
1646 You("release %s.", mon_nam(u.ustuck));
1648 You("%s
\82ð
\95ú
\82µ
\82½
\81D", mon_nam(u.ustuck));
1651 /* If holder is asleep or paralyzed:
1652 * 37.5% chance of getting away,
1653 * 12.5% chance of waking/releasing it;
1655 * 7.5% chance of getting away.
1656 * [strength ought to be a factor]
1657 * If holder is tame and there is no conflict,
1658 * guaranteed escape.
1660 switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
1666 You("pull free from %s.", mon_nam(u.ustuck));
1668 You("%s
\82ð
\82Ð
\82«
\82Í
\82È
\82µ
\82½
\81D", mon_nam(u.ustuck));
1672 if (!u.ustuck->mcanmove) {
1673 /* it's free to move on next turn */
1674 u.ustuck->mfrozen = 1;
1675 u.ustuck->msleeping = 0;
1679 if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf)
1682 You("cannot escape from %s!", mon_nam(u.ustuck));
1684 You("%s
\82©
\82ç
\93¦
\82°
\82ç
\82ê
\82È
\82¢
\81I", mon_nam(u.ustuck));
1693 /* Don't attack if you're running, and can see it */
1694 /* We should never get here if forcefight */
1695 if (context.run && ((!Blind && mon_visible(mtmp)
1696 && ((mtmp->m_ap_type != M_AP_FURNITURE
1697 && mtmp->m_ap_type != M_AP_OBJECT)
1698 || Protection_from_shape_changers))
1699 || sensemon(mtmp))) {
1713 /* attack monster */
1716 /* only attack if we know it's there */
1717 /* or if we used the 'F' command to fight blindly */
1718 /* or if it hides_under, in which case we call attack() to print
1719 * the Wait! message.
1720 * This is different from ceiling hiders, who aren't handled in
1724 /* If they used a 'm' command, trying to move onto a monster
1725 * prints the below message and wastes a turn. The exception is
1726 * if the monster is unseen and the player doesn't remember an
1727 * invisible monster--then, we fall through to attack() and
1728 * attack_check(), which still wastes a turn, but prints a
1729 * different message and makes the player remember the monster.
1732 && (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))) {
1733 if (mtmp->m_ap_type && !Protection_from_shape_changers
1735 stumble_onto_mimic(mtmp);
1736 else if (mtmp->mpeaceful && !Hallucination)
1738 pline("Pardon me, %s.", m_monnam(mtmp));
1740 pline("
\82¿
\82å
\82Á
\82Æ
\82²
\82ß
\82ñ
\82È
\82³
\82¢
\82æ
\81C%s
\82³
\82ñ
\81D", m_monnam(mtmp));
1743 You("move right into %s.", mon_nam(mtmp));
1745 You("%s
\82Ì
\82»
\82Î
\82É
\88Ú
\93®
\82µ
\82½
\81D", mon_nam(mtmp));
1748 if (context.forcefight || !mtmp->mundetected || sensemon(mtmp)
1749 || ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)
1750 && !is_safepet(mtmp))) {
1751 /* try to attack; note that it might evade */
1752 /* also, we don't attack tame when _safepet_ */
1758 /* specifying 'F' with no monster wastes a turn */
1759 if (context.forcefight
1760 /* remembered an 'I' && didn't use a move command */
1761 || (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
1762 struct obj *boulder = 0;
1763 boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
1764 solid = !accessible(x, y);
1765 int glyph = glyph_at(x, y); /* might be monster */
1769 boulder = sobj_at(BOULDER, x, y);
1770 /* if a statue is displayed at the target location,
1771 player is attempting to attack it [and boulder
1772 handling below is suitable for handling that] */
1773 if (glyph_is_statue(glyph)
1774 || (Hallucination && glyph_is_monster(glyph)))
1775 boulder = sobj_at(STATUE, x, y);
1777 /* force fight at boulder/statue or wall/door while wielding
1778 pick: start digging to break the boulder or wall */
1779 if (context.forcefight
1781 && uwep && dig_typ(uwep, x, y)
1782 /* should we dig? */
1783 && !glyph_is_invisible(glyph) && !glyph_is_monster(glyph)) {
1784 (void) use_pick_axe2(uwep);
1789 /* about to become known empty -- remove 'I' if present */
1792 map_object(boulder, TRUE);
1794 glyph = glyph_at(x, y); /* might have just changed */
1797 Strcpy(buf, ansimpleoname(boulder));
1798 else if (Underwater && !is_pool(x, y))
1799 /* Underwater, targetting non-water; the map just shows blank
1800 because you don't see remembered terrain while underwater;
1801 although the hero can attack an adjacent monster this way,
1802 assume he can't reach out far enough to distinguish terrain */
1804 Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
1808 Sprintf(buf, (Is_waterlevel(&u.uz) && levl[x][y].typ == AIR)
1809 ? "
\8bó
\8bC
\82Ì
\96A"
1810 : "
\89½
\82à
\82È
\82¢
\82Æ
\82±
\82ë");
1813 /* glyph might indicate unseen terrain if hero is blind;
1814 unlike searching, this won't reveal what that terrain is
1815 (except for solid rock, where the glyph would otherwise
1816 yield ludicrous "dark part of a room") */
1819 (levl[x][y].typ == STONE)
1821 : glyph_is_cmap(glyph)
1822 ? the(defsyms[glyph_to_cmap(glyph)].explanation)
1823 : (const char *) "an unknown obstacle");
1826 (levl[x][y].typ == STONE)
1828 : glyph_is_cmap(glyph)
1829 ? the(defsyms[glyph_to_cmap(glyph)].explanation)
1830 : (const char *) "
\95s
\96¾
\82È
\8fá
\8aQ
\95¨");
1832 /* note: 'solid' is misleadingly named and catches pools
1833 of water and lava as well as rock and walls */
1836 Strcpy(buf, "thin air");
1838 Strcpy(buf, "
\89½
\82à
\82È
\82¢
\8bó
\92\86");
1841 !(boulder || solid) ? "" : !explo ? "harmlessly " : "futilely ",
1842 explo ? "explode at" : "attack", buf);
1845 !(boulder || solid) ? "" : !explo ? "
\8cø
\89Ê
\82È
\82" : "
\82Þ
\82¾
\82É",
1846 buf, explo ? "
\82Å
\94\9a\94
\82µ
\82½" : "
\82ð
\8dU
\8c\82\82µ
\82½");
1852 u.mh = -1; /* dead in the current form */
1857 if (glyph_is_invisible(levl[x][y].glyph)) {
1861 /* not attacking an animal, so we try to move */
1862 if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
1871 if (!trapmove(x, y, trap))
1875 if (!test_move(u.ux, u.uy, x - u.ux, y - u.uy, DO_MOVE)) {
1876 if (!context.door_opened) {
1883 /* Move ball and chain. */
1885 if (!drag_ball(x, y, &bc_control, &ballx, &bally, &chainx, &chainy,
1886 &cause_delay, TRUE))
1889 /* Check regions entering/leaving */
1890 if (!in_out_region(x, y))
1893 /* now move the hero */
1897 /* Move your steed, too */
1899 u.usteed->mx = u.ux;
1900 u.usteed->my = u.uy;
1905 * If safepet at destination then move the pet to the hero's
1906 * previous location using the same conditions as in attack().
1907 * there are special extenuating circumstances:
1908 * (1) if the pet dies then your god angers,
1909 * (2) if the pet gets trapped then your god may disapprove,
1910 * (3) if the pet was already trapped and you attempt to free it
1911 * not only do you encounter the trap but you may frighten your
1912 * pet causing it to go wild! moral: don't abuse this privilege.
1914 * Ceiling-hiding pets are skipped by this section of code, to
1915 * be caught by the normal falling-monster code.
1917 if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
1918 /* if trapped, there's a chance the pet goes wild */
1919 if (mtmp->mtrapped) {
1920 if (!rn2(mtmp->mtame)) {
1921 mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
1923 m_unleash(mtmp, TRUE);
1929 mtmp->mundetected = 0;
1930 if (mtmp->m_ap_type)
1932 else if (!mtmp->mtame)
1933 newsym(mtmp->mx, mtmp->my);
1935 if (mtmp->mtrapped && (trap = t_at(mtmp->mx, mtmp->my)) != 0
1936 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
1937 && sobj_at(BOULDER, trap->tx, trap->ty)) {
1938 /* can't swap places with pet pinned in a pit by a boulder */
1939 u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
1940 } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
1941 /* can't swap places when pet can't move to your spot */
1942 u.ux = u.ux0, u.uy = u.uy0;
1944 You("stop. %s can't move diagonally.", upstart(y_monnam(mtmp)));
1946 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82Í
\8eÎ
\82ß
\82É
\93®
\82¯
\82È
\82¢
\81D", upstart(y_monnam(mtmp)));
1947 } else if (u.ux0 != x && u.uy0 != y && bad_rock(mtmp->data, x, u.uy0)
1948 && bad_rock(mtmp->data, u.ux0, y)
1949 && (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
1950 /* can't swap places when pet won't fit thru the opening */
1951 u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
1953 You("stop. %s won't fit through.", upstart(y_monnam(mtmp)));
1955 You("
\8e~
\82Ü
\82Á
\82½
\81D%s
\82Í
\92Ê
\82è
\94²
\82¯
\82ç
\82ê
\82È
\82¢
\81D", upstart(y_monnam(mtmp)));
1957 char pnambuf[BUFSZ];
1959 /* save its current description in case of polymorph */
1960 Strcpy(pnambuf, y_monnam(mtmp));
1962 remove_monster(x, y);
1963 place_monster(mtmp, u.ux0, u.uy0);
1965 newsym(u.ux0, u.uy0);
1968 You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
1973 mtmp->mtame ? "
\82Æ
\8fê
\8f\8a\82ð
\93ü
\82ê
\8a·
\82í
\82Á" : "
\82ð
\95|
\82ª
\82ç
\82¹");
1976 /* check for displacing it into pools and traps */
1977 switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
1980 case 1: /* trapped */
1981 case 3: /* changed levels */
1982 /* there's already been a trap message, reinforce it */
1987 /* drowned or died...
1988 * you killed your pet by direct action, so get experience
1989 * and possibly penalties;
1990 * we want the level gain message, if it happens, to occur
1991 * before the guilt message below
1994 /* minliquid() and mintrap() call mondead() rather than
1995 killed() so we duplicate some of the latter here */
1998 u.uconduct.killer++;
1999 mndx = monsndx(mtmp->data);
2000 tmp = experience(mtmp, (int) mvitals[mndx].died);
2001 more_experienced(tmp, 0);
2002 newexplevel(); /* will decide if you go up */
2004 /* That's no way to treat a pet! Your god gets angry.
2006 * [This has always been pretty iffy. Why does your
2007 * patron deity care at all, let alone enough to get mad?]
2011 You_feel("guilty about losing your pet like this.");
2013 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");
2019 pline("that's strange, unknown mintrap result!");
2025 reset_occupations();
2027 if (context.run < 8)
2028 if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ)
2029 || IS_FURNITURE(tmpr->typ))
2033 if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) || u.dx
2035 (void) hideunder(&youmonst);
2038 * Mimics (or whatever) become noticeable if they move and are
2039 * imitating something that doesn't move. We could extend this
2040 * to non-moving monsters...
2042 if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT
2043 || youmonst.m_ap_type == M_AP_FURNITURE))
2044 youmonst.m_ap_type = M_AP_NOTHING;
2046 check_leash(u.ux0, u.uy0);
2048 if (u.ux0 != u.ux || u.uy0 != u.uy) {
2050 /* Clean old position -- vision_recalc() will print our new one. */
2051 newsym(u.ux0, u.uy0);
2052 /* Since the hero has moved, adjust what can be seen/unseen. */
2053 vision_recalc(1); /* Do the work now in the recover time. */
2054 invocation_message();
2057 if (Punished) /* put back ball and chain */
2058 move_bc(0, bc_control, ballx, bally, chainx, chainy);
2062 /* delay next move because of ball dragging */
2063 /* must come after we finished picking up, in spoteffects() */
2066 multi_reason = "dragging an iron ball";
2070 if (context.run && flags.runmode != RUN_TPORT) {
2071 /* display every step or every 7th step depending upon mode */
2072 if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
2077 if (flags.runmode == RUN_CRAWL) {
2087 /* combat increases metabolism */
2091 /* this used to be part of domove() when moving to a monster's
2092 position, but is now called by attack() so that it doesn't
2093 execute if you decline to attack a peaceful monster */
2095 if ((moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) {
2096 int *hp = (!Upolyd ? &u.uhp : &u.mh);
2102 You("pass out from exertion!");
2104 You("
\8bC
\90â
\82µ
\82½
\81D");
2105 exercise(A_CON, FALSE);
2106 fall_asleep(-10, FALSE);
2109 return (boolean) (multi < 0); /* might have fainted (forced to sleep) */
2113 invocation_message()
2115 /* a special clue-msg when on the Invocation position */
2116 if (invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
2118 struct obj *otmp = carrying(CANDELABRUM_OF_INVOCATION);
2120 nomul(0); /* stop running or travelling */
2123 Sprintf(buf, "beneath %s", y_monnam(u.usteed));
2125 Sprintf(buf, "%s
\82Ì
\89º
\82É", y_monnam(u.usteed));
2126 else if (Levitation || Flying)
2128 Strcpy(buf, "beneath you");
2130 Strcpy(buf, "
\89º
\95û
\82É");
2133 Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
2135 Strcpy(buf, "
\91«
\8c³
\82É");
2138 You_feel("a strange vibration %s.", buf);
2140 You("%s
\8aï
\96
\82È
\90U
\93®
\82ð
\8a´
\82¶
\82½
\81D", buf);
2141 u.uevent.uvibrated = 1;
2142 if (otmp && otmp->spe == 7 && otmp->lamplit)
2144 pline("%s %s!", The(xname(otmp)),
2145 Blind ? "throbs palpably" : "glows with a strange light");
2147 pline("%s
\82Í%s
\82µ
\82½
\81I", The(xname(otmp)),
2148 Blind ? "
\82©
\82·
\82©
\82É
\90U
\93®" : "
\8aï
\96
\82È
\8cõ
\82ð
\94");
2153 /* moving onto different terrain;
2154 might be going into solid rock, inhibiting levitation or flight,
2155 or coming back out of such, reinstating levitation/flying */
2159 struct rm *lev = &levl[u.ux][u.uy];
2160 boolean blocklev = (IS_ROCK(lev->typ) || closed_door(u.ux, u.uy)
2161 || (Is_waterlevel(&u.uz) && lev->typ == WATER));
2164 /* called from spoteffects(), skip float_down() */
2167 You_cant("levitate in here.");
2169 You_cant("
\82±
\82±
\82Å
\82Í
\95\82\97V
\82Å
\82«
\82È
\82¢
\81D");
2170 BLevitation |= FROMOUTSIDE;
2171 } else if (BLevitation) {
2172 BLevitation &= ~FROMOUTSIDE;
2176 /* the same terrain that blocks levitation also blocks flight */
2180 You_cant("fly in here.");
2182 You_cant("
\82±
\82±
\82Å
\82Í
\94ò
\82×
\82È
\82¢
\81D");
2183 BFlying |= FROMOUTSIDE;
2184 } else if (BFlying) {
2185 BFlying &= ~FROMOUTSIDE;
2186 float_vs_flight(); /* maybe toggle (BFlying & I_SPECIAL) */
2187 /* [minor bug: we don't know whether this is beginning flight or
2188 resuming it; that could be tracked so that this message could
2189 be adjusted to "resume flying", but isn't worth the effort...] */
2192 You("start flying.");
2194 You("
\94ò
\82Ñ
\82Í
\82¶
\82ß
\82½
\81D");
2198 /* extracted from spoteffects; called by spoteffects to check for entering or
2199 leaving a pool of water/lava, and by moveloop to check for staying on one
2201 returns true to skip rest of spoteffects */
2203 pooleffects(newspot)
2204 boolean newspot; /* true if called by spoteffects */
2206 /* check for leaving water */
2208 boolean still_inwater = FALSE; /* assume we're getting out */
2210 if (!is_pool(u.ux, u.uy)) {
2211 if (Is_waterlevel(&u.uz))
2213 You("pop into an air bubble.");
2215 You("
\82Ð
\82å
\82¢
\82Æ
\8bó
\8bC
\82Ì
\96A
\82É
\93ü
\82Á
\82½
\81D");
2216 else if (is_lava(u.ux, u.uy))
2218 You("leave the water..."); /* oops! */
2220 You("
\90\85\82©
\82ç
\94²
\82¯
\82¾
\82µ
\82½
\81D
\81D
\81D"); /* oops! */
2224 You("are on solid %s again.",
2225 is_ice(u.ux, u.uy) ? "ice" : "land");
2227 You("
\8cÅ
\82¢%s
\82Ì
\8fã
\82É
\82Ü
\82½
\96ß
\82Á
\82½
\81D",
2228 is_ice(u.ux, u.uy) ? "
\95X" : "
\92n
\96Ê");
2230 } else if (Is_waterlevel(&u.uz)) {
2231 still_inwater = TRUE;
2232 } else if (Levitation) {
2234 You("pop out of the water like a cork!");
2236 You("
\83R
\83\8b\83N
\82Ì
\82æ
\82¤
\82É
\94ò
\82Ñ
\82¾
\82µ
\82½
\81I");
2237 } else if (Flying) {
2239 You("fly out of the water.");
2241 You("
\90\85\82©
\82ç
\94ò
\82Ñ
\82¾
\82µ
\82½
\81D");
2242 } else if (Wwalking) {
2244 You("slowly rise above the surface.");
2246 You("
\82ä
\82Á
\82
\82è
\90\85\96Ê
\82Ü
\82Å
\8fã
\82ª
\82Á
\82½
\81D");
2248 still_inwater = TRUE;
2250 if (!still_inwater) {
2251 boolean was_underwater = (Underwater && !Is_waterlevel(&u.uz));
2253 u.uinwater = 0; /* leave the water */
2254 if (was_underwater) { /* restore vision */
2256 vision_full_recalc = 1;
2261 /* check for entering water or lava */
2262 if (!u.ustuck && !Levitation && !Flying && is_pool_or_lava(u.ux, u.uy)) {
2264 && (is_flyer(u.usteed->data) || is_floater(u.usteed->data)
2265 || is_clinger(u.usteed->data))) {
2266 /* floating or clinging steed keeps hero safe (is_flyer() test
2267 is redundant; it can't be true since Flying yielded false) */
2269 } else if (u.usteed) {
2270 /* steed enters pool */
2271 dismount_steed(Underwater ? DISMOUNT_FELL : DISMOUNT_GENERIC);
2272 /* dismount_steed() -> float_down() -> pickup()
2273 (float_down doesn't do autopickup on Air or Water) */
2274 if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz))
2276 /* even if we actually end up at same location, float_down()
2277 has already done spoteffect()'s trap and pickup actions */
2279 check_special_room(FALSE); /* spoteffects */
2284 /* drown(),lava_effects() return true if hero changes
2285 location while surviving the problem */
2286 if (is_lava(u.ux, u.uy)) {
2289 } else if (!Wwalking
2290 && (newspot || !u.uinwater || !(Swimming || Amphibious))) {
2302 static int inspoteffects = 0;
2303 static coord spotloc;
2304 static int spotterrain;
2305 static struct trap *spottrap = (struct trap *) 0;
2306 static unsigned spottraptyp = NO_TRAP;
2307 struct trap *trap = t_at(u.ux, u.uy);
2308 register struct monst *mtmp;
2310 /* prevent recursion from affecting the hero all over again
2311 [hero poly'd to iron golem enters water here, drown() inflicts
2312 damage that triggers rehumanize() which calls spoteffects()...] */
2313 if (inspoteffects && u.ux == spotloc.x && u.uy == spotloc.y
2314 /* except when reason is transformed terrain (ice -> water) */
2315 && spotterrain == levl[u.ux][u.uy].typ
2316 /* or transformed trap (land mine -> pit) */
2317 && (!spottrap || !trap || trap->ttyp == spottraptyp))
2321 spotterrain = levl[u.ux][u.uy].typ;
2322 spotloc.x = u.ux, spotloc.y = u.uy;
2324 /* moving onto different terrain might cause Levitation to toggle */
2325 if (spotterrain != levl[u.ux0][u.uy0].typ || !on_level(&u.uz, &u.uz0))
2328 if (pooleffects(TRUE))
2331 check_special_room(FALSE);
2332 if (IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
2334 if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
2337 /* if levitation is due to time out at the end of this
2338 turn, allowing it to do so could give the perception
2339 that a trap here is being triggered twice, so adjust
2340 the timeout to prevent that */
2341 if (trap && (HLevitation & TIMEOUT) == 1L && !ELevitation
2342 && !(HLevitation & ~TIMEOUT)) {
2343 if (rn2(2)) { /* defer timeout */
2344 incr_itimeout(&HLevitation, 1L);
2345 } else { /* timeout early */
2346 if (float_down(I_SPECIAL | TIMEOUT, 0L)) {
2347 /* levitation has ended; we've already triggered
2348 any trap and [usually] performed autopickup */
2355 * If not a pit, pickup before triggering trap.
2356 * If pit, trigger trap before pickup.
2358 pit = (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT));
2364 * dotrap on a fire trap calls melt_ice() which triggers
2365 * spoteffects() (again) which can trigger the same fire
2366 * trap (again). Use static spottrap to prevent that.
2367 * We track spottraptyp because some traps morph
2368 * (landmine to pit) and any new trap type
2369 * should get triggered.
2371 if (!spottrap || spottraptyp != trap->ttyp) {
2373 spottraptyp = trap->ttyp;
2374 dotrap(trap, 0); /* fall into arrow trap, etc. */
2375 spottrap = (struct trap *) 0;
2376 spottraptyp = NO_TRAP;
2382 /* Warning alerts you to ice danger */
2383 if (Warning && is_ice(u.ux, u.uy)) {
2384 static const char *const icewarnings[] = {
2386 "The ice seems very soft and slushy.",
2387 "You feel the ice shift beneath you!",
2388 "The ice, is gonna BREAK!", /* The Dead Zone */
2390 "
\95X
\82Í
\82Æ
\82Ä
\82à
\93î
\82ç
\82©
\82
\82Ä
\97n
\82¯
\82»
\82¤
\82¾
\81D",
2391 "
\82 \82È
\82½
\82Ì
\89º
\82Ì
\95X
\82ª
\93®
\82¢
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81I",
2392 "
\95X
\82ª
\89ó
\82ê
\82é
\82¼
\81I", /* The Dead Zone */
2395 long time_left = spot_time_left(u.ux, u.uy, MELT_ICE_AWAY);
2396 if (time_left && time_left < 15L)
2397 pline1((time_left < 5L) ? icewarnings[2] : (time_left < 10L)
2401 if ((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) {
2402 mtmp->mundetected = mtmp->msleeping = 0;
2403 switch (mtmp->data->mlet) {
2406 pline("%s suddenly drops from the %s!", Amonnam(mtmp),
2407 ceiling(u.ux, u.uy));
2409 pline("%s
\82ª
\93Ë
\91R%s
\82©
\82ç
\97\8e\82¿
\82Ä
\82«
\82½
\81I",
2410 Amonnam(mtmp), ceiling(u.ux,u.uy));
2412 if (mtmp->mtame) /* jumps to greet you, not attack */
2414 else if (uarmh && is_metallic(uarmh))
2416 pline("Its blow glances off your %s.",
2418 pline("
\8dU
\8c\82\82Í
\82 \82È
\82½
\82Ì%s
\82ð
\82©
\82·
\82ß
\82½
\82¾
\82¯
\82¾
\82Á
\82½
\81D",
2419 helm_simple_name(uarmh));
2420 else if (u.uac + 3 <= rnd(20))
2422 You("are almost hit by %s!",
2423 x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE));
2425 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",
2426 x_monnam(mtmp, ARTICLE_A, "", 0, TRUE));
2431 You("are hit by %s!",
2432 x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE));
2434 You("
\97\8e\82¿
\82Ä
\82«
\82½%s
\82É
\93\96\82½
\82Á
\82½
\81I",
2435 x_monnam(mtmp, ARTICLE_A, "", 0, TRUE));
2438 if (Half_physical_damage)
2439 dmg = (dmg + 1) / 2;
2440 mdamageu(mtmp, dmg);
2443 default: /* monster surprises you. */
2446 pline("%s jumps near you from the %s.", Amonnam(mtmp),
2447 ceiling(u.ux, u.uy));
2449 pline("%s
\82ª%s
\82©
\82ç
\82 \82È
\82½
\82Ì
\8bß
\82
\82É
\94ò
\82ñ
\82Å
\82«
\82½
\81D", Amonnam(mtmp),
2450 ceiling(u.ux,u.uy));
2452 else if (mtmp->mpeaceful) {
2456 You("%s
\82ð
\8bÁ
\82©
\82µ
\82½
\81I",
2457 Blind && !sensemon(mtmp) ? something : a_monnam(mtmp));
2458 mtmp->mpeaceful = 0;
2461 pline("%s attacks you by surprise!", Amonnam(mtmp));
2463 pline("%s
\82Í
\8bÁ
\82¢
\82Ä
\82 \82È
\82½
\82ð
\8dU
\8c\82\82µ
\82½
\81I", Amonnam(mtmp));
2466 mnexto(mtmp); /* have to move the monster */
2469 if (!--inspoteffects) {
2470 spotterrain = STONE; /* 0 */
2471 spotloc.x = spotloc.y = 0;
2476 /* returns first matching monster */
2477 STATIC_OVL struct monst *
2478 monstinroom(mdat, roomno)
2479 struct permonst *mdat;
2482 register struct monst *mtmp;
2484 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2485 if (DEADMONSTER(mtmp))
2487 if (mtmp->data == mdat
2488 && index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET))
2491 return (struct monst *) 0;
2495 in_rooms(x, y, typewanted)
2496 register xchar x, y;
2497 register int typewanted;
2500 char rno, *ptr = &buf[4];
2501 int typefound, min_x, min_y, max_x, max_y_offset, step;
2502 register struct rm *lev;
2504 #define goodtype(rno) \
2506 || ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) \
2507 || ((typewanted == SHOPBASE) && (typefound > SHOPBASE)))
2509 switch (rno = levl[x][y].roomno) {
2518 default: /* i.e. a regular room # */
2528 else if (x >= COLNO)
2535 max_y_offset -= step;
2536 } else if ((min_y + max_y_offset) >= ROWNO)
2537 max_y_offset -= step;
2539 for (x = min_x; x <= max_x; x += step) {
2540 lev = &levl[x][min_y];
2542 if (((rno = lev[y].roomno) >= ROOMOFFSET) && !index(ptr, rno)
2546 if (y > max_y_offset)
2548 if (((rno = lev[y].roomno) >= ROOMOFFSET) && !index(ptr, rno)
2552 if (y > max_y_offset)
2554 if (((rno = lev[y].roomno) >= ROOMOFFSET) && !index(ptr, rno)
2561 /* is (x,y) in a town? */
2566 s_level *slev = Is_special(&u.uz);
2567 register struct mkroom *sroom;
2568 boolean has_subrooms = FALSE;
2570 if (!slev || !slev->flags.town)
2574 * See if (x,y) is in a room with subrooms, if so, assume it's the
2575 * town. If there are no subrooms, the whole level is in town.
2577 for (sroom = &rooms[0]; sroom->hx > 0; sroom++) {
2578 if (sroom->nsubrooms > 0) {
2579 has_subrooms = TRUE;
2580 if (inside_room(sroom, x, y))
2585 return !has_subrooms;
2590 register boolean newlev;
2592 char *ptr1, *ptr2, *ptr3, *ptr4;
2594 Strcpy(u.urooms0, u.urooms);
2595 Strcpy(u.ushops0, u.ushops);
2598 u.uentered[0] = '\0';
2600 u.ushops_entered[0] = '\0';
2601 Strcpy(u.ushops_left, u.ushops0);
2604 Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0));
2606 for (ptr1 = &u.urooms[0], ptr2 = &u.uentered[0], ptr3 = &u.ushops[0],
2607 ptr4 = &u.ushops_entered[0];
2609 if (!index(u.urooms0, *ptr1))
2611 if (IS_SHOP(*ptr1 - ROOMOFFSET)) {
2613 if (!index(u.ushops0, *ptr1))
2621 /* filter u.ushops0 -> u.ushops_left */
2622 for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++)
2623 if (!index(u.ushops, *ptr1))
2629 check_special_room(newlev)
2630 register boolean newlev;
2632 register struct monst *mtmp;
2635 move_update(newlev);
2638 u_left_shop(u.ushops_left, newlev);
2640 if (!*u.uentered && !*u.ushops_entered) /* implied by newlev */
2641 return; /* no entrance messages necessary */
2643 /* Did we just enter a shop? */
2644 if (*u.ushops_entered)
2645 u_entered_shop(u.ushops_entered);
2647 for (ptr = &u.uentered[0]; *ptr; ptr++) {
2648 int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype;
2649 boolean msg_given = TRUE;
2651 /* Did we just enter some other special room? */
2652 /* vault.c insists that a vault remain a VAULT,
2653 * and temples should remain TEMPLEs,
2654 * but everything else gives a message only the first time */
2658 pline("Welcome to David's treasure zoo!");
2660 pline("
\83f
\83r
\83b
\83g
\95ó
\94 \93®
\95¨
\89\80\82É
\82æ
\82¤
\82±
\82»
\81I");
2664 pline("It %s rather %s down here.", Blind ? "feels" : "looks",
2665 Blind ? "humid" : "muddy");
2667 pline("
\82©
\82È
\82è%s
\81D",
2668 Blind ? "
\8e¼
\8bC
\82ª
\82 \82é
\8fê
\8f\8a\82Ì
\82æ
\82¤
\82¾"
2669 : "
\82Ç
\82ë
\82Ç
\82ë
\82µ
\82Ä
\82¢
\82é
\8fê
\8f\8a\82¾");
2674 You("enter an opulent throne room!");
2676 You("
\89Ø
\82â
\82©
\82È
\8bÊ
\8dÀ
\82Ì
\8aÔ
\82É
\93ü
\82Á
\82½
\81I");
2680 You("enter a leprechaun hall!");
2682 You("
\83\8c\83v
\83\89\83R
\81[
\83\93\83z
\81[
\83\8b\82É
\93ü
\82Á
\82½
\81I");
2687 const char *run = locomotion(youmonst.data, "Run");
2688 pline("%s away! %s away!", run, run);
2690 pline("
\93¦
\82°
\82ë
\81I
\93¦
\82°
\82ë
\81I");
2694 You("have an uncanny feeling...");
2696 You("
\95s
\8bC
\96¡
\82È
\8a´
\82¶
\82ª
\82µ
\82½
\81D
\81D
\81D");
2700 You("enter a giant beehive!");
2702 You("
\8b\90\91å
\82È
\96I
\82Ì
\91\83\82É
\93ü
\82Á
\82½
\81I");
2706 You("enter a disgusting nest!");
2708 You("
\82Þ
\82Á
\82Æ
\82·
\82é
\8fL
\82¢
\82Ì
\82·
\82é
\92¹
\82Ì
\91\83\82É
\93ü
\82Á
\82½
\81I");
2712 You("enter an anthole!");
2714 You("
\83A
\83\8a\82Ì
\91\83\82É
\93ü
\82Á
\82½
\81I");
2717 if (monstinroom(&mons[PM_SOLDIER], roomno)
2718 || monstinroom(&mons[PM_SERGEANT], roomno)
2719 || monstinroom(&mons[PM_LIEUTENANT], roomno)
2720 || monstinroom(&mons[PM_CAPTAIN], roomno))
2722 You("enter a military barracks!");
2724 You("
\8cR
\91à
\82Ì
\95ºäq
\82É
\93ü
\82Á
\82½
\81I");
2727 You("enter an abandoned barracks.");
2729 You("
\95ú
\92u
\82³
\82ê
\82½
\82Ü
\82Ü
\82Ì
\95ºäq
\82É
\93ü
\82Á
\82½
\81D");
2732 struct monst *oracle = monstinroom(&mons[PM_ORACLE], roomno);
2734 if (!oracle->mpeaceful)
2736 verbalize("You're in Delphi, %s.", plname);
2738 verbalize("
\82¨
\82Ü
\82¦
\82Í
\83f
\83\8b\83t
\83@
\83C
\82Ì
\90_
\91õ
\8f\8a\82É
\82¢
\82é
\81D");
2741 verbalize("%s, %s, welcome to Delphi!",
2742 Hello((struct monst *) 0), plname);
2744 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",
2752 intemple(roomno + ROOMOFFSET);
2755 msg_given = (rt == TEMPLE);
2760 room_discovered(roomno);
2763 rooms[roomno].rtype = OROOM;
2764 if (!search_special(rt)) {
2765 /* No more room of that type */
2768 level.flags.has_court = 0;
2771 level.flags.has_swamp = 0;
2774 level.flags.has_morgue = 0;
2777 level.flags.has_zoo = 0;
2780 level.flags.has_barracks = 0;
2783 level.flags.has_temple = 0;
2786 level.flags.has_beehive = 0;
2790 if (rt == COURT || rt == SWAMP || rt == MORGUE || rt == ZOO)
2791 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
2792 if (DEADMONSTER(mtmp))
2794 if (!Stealth && !rn2(3))
2795 mtmp->msleeping = 0;
2807 struct trap *traphere = t_at(u.ux, u.uy);
2808 /* awful kludge to work around parse()'s pre-decrement */
2809 count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
2810 multi = 0; /* always reset */
2811 /* uswallow case added by GAN 01/29/87 */
2813 if (!u.ustuck->minvent) {
2814 if (is_animal(u.ustuck->data)) {
2816 You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck)));
2818 You("%s
\82Ì
\90ã
\82ð
\8fE
\82Á
\82½
\81D", mon_nam(u.ustuck));
2820 pline("But it's kind of slimy, so you drop it.");
2822 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");
2825 You("don't %s anything in here to pick up.",
2826 Blind ? "feel" : "see");
2828 pline("
\82±
\82±
\82É
\82Í
\8fE
\82¦
\82é
\82à
\82Ì
\82ª
\82È
\82¢%s
\81D",
2829 Blind ? "
\82æ
\82¤
\82¾" : "");
2833 int tmpcount = -count;
2834 return loot_mon(u.ustuck, &tmpcount, (boolean *) 0);
2837 if (is_pool(u.ux, u.uy)) {
2838 if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
2839 || (Flying && !Breathless)) {
2841 You("cannot dive into the water to pick things up.");
2843 You("
\95¨
\82ð
\8fE
\82¢
\82 \82°
\82é
\82½
\82ß
\82É
\90\85\82É
\94ò
\82Ñ
\82±
\82ß
\82È
\82¢
\81D");
2845 } else if (!Underwater) {
2847 You_cant("even see the bottom, let alone pick up %s.", something);
2849 pline("
\92ê
\82³
\82¦
\8c©
\82¦
\82È
\82¢
\81C
\8fE
\82¤
\82Ì
\82Í
\82â
\82ß
\82æ
\82¤
\81D");
2853 if (is_lava(u.ux, u.uy)) {
2854 if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)
2855 || (Flying && !Breathless)) {
2857 You_cant("reach the bottom to pick things up.");
2859 You_cant("
\95¨
\82ð
\8fE
\82¢
\8fã
\82°
\82é
\82½
\82ß
\82É
\92ê
\82Ü
\82Å
\82¢
\82¯
\82È
\82¢
\81D");
2861 } else if (!likes_lava(youmonst.data)) {
2863 You("would burn to a crisp trying to pick things up.");
2865 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");
2869 if (!OBJ_AT(u.ux, u.uy)) {
2870 register struct rm *lev = &levl[u.ux][u.uy];
2871 if (IS_THRONE(lev->typ))
2873 pline("It must weigh%s a ton!", lev->looted ? " almost" : "");
2875 pline("
\82±
\82ê
\82Í%s
\8fd
\82¢
\81I", lev->looted ? "
\82©
\82È
\82è" : "
\82·
\82²
\82");
2876 else if (IS_SINK(lev->typ))
2878 pline_The("plumbing connects it to the floor.");
2880 pline_The("
\94z
\8aÇ
\82Í
\8f°
\82É
\82Â
\82È
\82ª
\82Á
\82Ä
\82¢
\82é
\81D");
2881 else if (IS_GRAVE(lev->typ))
2883 You("don't need a gravestone. Yet.");
2885 pline("
\82 \82È
\82½
\82É
\82Í
\95æ
\90Î
\82Í
\95s
\97v
\82¾
\81D
\81D
\81D
\8d¡
\82Ì
\82Æ
\82±
\82ë
\81D");
2886 else if (IS_FOUNTAIN(lev->typ))
2888 You("could drink the water...");
2890 You("
\90\85\82ð
\88ù
\82ß
\82È
\82¢
\81D
\81D
\81D");
2891 else if (IS_DOOR(lev->typ) && (lev->doormask & D_ISOPEN))
2893 pline("It won't come off the hinges.");
2895 pline("
\83q
\83\93\83W
\82ð
\8aO
\82¹
\82È
\82¢
\81D");
2898 There("is nothing here to pick up.");
2900 pline("
\82±
\82±
\82É
\82Í
\8fE
\82¦
\82é
\82à
\82Ì
\82Í
\82È
\82¢
\81D");
2903 if (!can_reach_floor(TRUE)) {
2904 if (traphere && uteetering_at_seen_pit(traphere))
2906 You("cannot reach the bottom of the pit.");
2908 You("
\97\8e\82µ
\8c\8a\82Ì
\92ê
\82É%s
\82ª
\93Í
\82©
\82È
\82©
\82Á
\82½
\81D", body_part(HAND));
2909 else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
2911 else if (Blind && !can_reach_floor(TRUE))
2913 You("cannot reach anything here.");
2915 You("
\89½
\82É
\82à
\93Í
\82©
\82È
\82¢
\81D");
2918 You("cannot reach the %s.", surface(u.ux, u.uy));
2920 You("%s
\82É
\82½
\82Ç
\82è
\82Â
\82
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D", surface(u.ux, u.uy));
2924 return pickup(-count);
2927 /* stop running if we see something interesting */
2928 /* turn around a corner if that is the only way we can proceed */
2929 /* do not turn left or right twice */
2933 register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9;
2934 register int corrct = 0, noturn = 0;
2935 register struct monst *mtmp;
2936 register struct trap *trap;
2938 /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */
2939 /* they polymorphed while in the middle of a long move. */
2940 if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) {
2945 if (Blind || context.run == 0)
2947 for (x = u.ux - 1; x <= u.ux + 1; x++)
2948 for (y = u.uy - 1; y <= u.uy + 1; y++) {
2952 if (u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy)
2955 if (x == u.ux && y == u.uy)
2958 if ((mtmp = m_at(x, y)) && mtmp->m_ap_type != M_AP_FURNITURE
2959 && mtmp->m_ap_type != M_AP_OBJECT
2960 && (!mtmp->minvis || See_invisible) && !mtmp->mundetected) {
2961 if ((context.run != 1 && !mtmp->mtame)
2962 || (x == u.ux + u.dx && y == u.uy + u.dy))
2966 if (levl[x][y].typ == STONE)
2968 if (x == u.ux - u.dx && y == u.uy - u.dy)
2971 if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM)
2972 || IS_AIR(levl[x][y].typ))
2974 else if (closed_door(x, y)
2975 || (mtmp && is_door_mappear(mtmp))) {
2976 if (x != u.ux && y != u.uy)
2978 if (context.run != 1)
2981 } else if (levl[x][y].typ == CORR) {
2983 if (levl[u.ux][u.uy].typ != ROOM) {
2984 if (context.run == 1 || context.run == 3
2985 || context.run == 8) {
2986 i = dist2(x, y, u.ux + u.dx, u.uy + u.dy);
2989 if (corrct == 1 && dist2(x, y, x0, y0) != 1)
3001 } else if ((trap = t_at(x, y)) && trap->tseen) {
3002 if (context.run == 1)
3003 goto bcorr; /* if you must */
3004 if (x == u.ux + u.dx && y == u.uy + u.dy)
3007 } else if (is_pool_or_lava(x, y)) {
3008 /* water and lava only stop you if directly in front, and stop
3009 * you even if you are running
3011 if (!Levitation && !Flying && !is_clinger(youmonst.data)
3012 && x == u.ux + u.dx && y == u.uy + u.dy)
3013 /* No Wwalking check; otherwise they'd be able
3014 * to test boots by trying to SHIFT-direction
3015 * into a pool and seeing if the game allowed it
3019 } else { /* e.g. objects or trap or stairs */
3020 if (context.run == 1)
3022 if (context.run == 8)
3026 if (((x == u.ux - u.dx) && (y != u.uy + u.dy))
3027 || ((y == u.uy - u.dy) && (x != u.ux + u.dx)))
3033 } /* end for loops */
3035 if (corrct > 1 && context.run == 2)
3037 if ((context.run == 1 || context.run == 3 || context.run == 8) && !noturn
3038 && !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) {
3039 /* make sure that we do not turn too far */
3041 if (u.dx == y0 - u.uy && u.dy == u.ux - x0)
3042 i = 2; /* straight turn right */
3044 i = -2; /* straight turn left */
3045 } else if (u.dx && u.dy) {
3046 if ((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy))
3047 i = -1; /* half turn left */
3049 i = 1; /* half turn right */
3051 if ((x0 - u.ux == y0 - u.uy && !u.dy)
3052 || (x0 - u.ux != y0 - u.uy && u.dy))
3053 i = 1; /* half turn right */
3055 i = -1; /* half turn left */
3058 i += u.last_str_turn;
3059 if (i <= 2 && i >= -2) {
3060 u.last_str_turn = i;
3067 /* check for a doorway which lacks its door (NODOOR or BROKEN) */
3072 struct rm *lev_p = &levl[x][y];
3074 if (!IS_DOOR(lev_p->typ))
3076 /* all rogue level doors are doorless but disallow diagonal access, so
3077 we treat them as if their non-existant doors were actually present */
3078 if (Is_rogue_level(&u.uz))
3080 return !(lev_p->doormask & ~(D_NODOOR | D_BROKEN));
3083 /* used by drown() to check whether hero can crawl from water to <x,y> */
3085 crawl_destination(x, y)
3088 /* is location ok in general? */
3089 if (!goodpos(x, y, &youmonst, 0))
3092 /* orthogonal movement is unrestricted when destination is ok */
3093 if (x == u.ux || y == u.uy)
3096 /* diagonal movement has some restrictions */
3097 if (NODIAG(u.umonnum))
3098 return FALSE; /* poly'd into a grid bug... */
3100 return TRUE; /* or a xorn... */
3101 /* pool could be next to a door, conceivably even inside a shop */
3102 if (IS_DOOR(levl[x][y].typ) && (!doorless_door(x, y) || block_door(x, y)))
3104 /* finally, are we trying to squeeze through a too-narrow gap? */
3105 return !(bad_rock(youmonst.data, u.ux, y)
3106 && bad_rock(youmonst.data, x, u.uy));
3109 /* something like lookaround, but we are not running */
3110 /* react only to monsters that might hit us */
3115 register struct monst *mtmp;
3117 /* Also see the similar check in dochugw() in monmove.c */
3118 for (x = u.ux - 1; x <= u.ux + 1; x++)
3119 for (y = u.uy - 1; y <= u.uy + 1; y++) {
3122 if (x == u.ux && y == u.uy)
3124 if ((mtmp = m_at(x, y)) && mtmp->m_ap_type != M_AP_FURNITURE
3125 && mtmp->m_ap_type != M_AP_OBJECT
3126 && (!mtmp->mpeaceful || Hallucination)
3127 && (!is_hider(mtmp->data) || !mtmp->mundetected)
3128 && !noattacks(mtmp->data) && mtmp->mcanmove
3129 && !mtmp->msleeping /* aplvax!jcn */
3130 && !onscary(u.ux, u.uy, mtmp) && canspotmon(mtmp))
3141 return; /* This is a bug fix by ab@unido */
3142 u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
3146 multi_reason = NULL;
3147 context.travel = context.travel1 = context.mv = context.run = 0;
3150 /* called when a non-movement, multi-turn action has completed */
3153 const char *msg_override;
3155 multi = 0; /* caller will usually have done this already */
3157 nomovemsg = msg_override;
3158 else if (!nomovemsg)
3159 nomovemsg = You_can_move_again;
3164 multi_reason = NULL;
3173 static short powers[] = { TELEPORT, SEE_INVIS, POISON_RES, COLD_RES,
3174 SHOCK_RES, FIRE_RES, SLEEP_RES, DISINT_RES,
3175 TELEPORT_CONTROL, STEALTH, FAST, INVIS };
3177 if (moves <= wailmsg + 50)
3181 if (Role_if(PM_WIZARD) || Race_if(PM_ELF) || Role_if(PM_VALKYRIE)) {
3186 who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? urole.name.m
3189 who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? urole.name.m
3194 pline("%s is about to die.", who);
3196 pline("%s
\82Í
\8e\80\82É
\82©
\82¯
\82Ä
\82¢
\82é
\81D", who);
3198 for (i = 0, powercnt = 0; i < SIZE(powers); ++i)
3199 if (u.uprops[powers[i]].intrinsic & INTRINSIC)
3203 pline(powercnt >= 4 ? "%s, all your powers will be lost..."
3205 pline(powercnt >= 4 ? "%s
\81C
\82 \82È
\82½
\82Ì
\91S
\82Ä
\82Ì
\97Í
\82Í
\8e¸
\82í
\82ê
\82Â
\82Â
\82 \82é
\81D
\81D
\81D"
3207 : "%s, your life force is running out.",
3209 : "%s
\81C
\82 \82È
\82½
\82Ì
\90¶
\96½
\97Í
\82Í
\90s
\82«
\82æ
\82¤
\82Æ
\82µ
\82Ä
\82¢
\82é
\81D
\81D
\81D",
3214 You_hear(u.uhp == 1 ? "the wailing of the Banshee..."
3216 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"
3218 : "the howling of the CwnAnnwn...");
3220 : "
\83N
\81[
\83\93\81E
\83A
\83\93\83k
\81[
\83\93\82Ì
\89\93\96i
\82ª
\95·
\82±
\82¦
\82é
\81D
\81D
\81D");
3225 losehp(n, knam, k_format)
3227 register const char *knam;
3237 else if (n > 0 && u.mh * 10 < u.mhmax && Unchanging)
3243 if (u.uhp > u.uhpmax)
3244 u.uhpmax = u.uhp; /* perhaps n was negative */
3247 killer.format = k_format;
3248 if (killer.name != knam) /* the thing that killed you */
3249 Strcpy(killer.name, knam ? knam : "");
3253 pline("
\82 \82È
\82½
\82Í
\8e\80\82É
\82Ü
\82µ
\82½
\81D
\81D
\81D");
3255 } else if (n > 0 && u.uhp * 10 < u.uhpmax) {
3263 register long carrcap;
3265 carrcap = 25 * (ACURRSTR + ACURR(A_CON)) + 50;
3267 /* consistent with can_carry() in mon.c */
3268 if (youmonst.data->mlet == S_NYMPH)
3269 carrcap = MAX_CARR_CAP;
3270 else if (!youmonst.data->cwt)
3271 carrcap = (carrcap * (long) youmonst.data->msize) / MZ_HUMAN;
3272 else if (!strongmonst(youmonst.data)
3273 || (strongmonst(youmonst.data)
3274 && (youmonst.data->cwt > WT_HUMAN)))
3275 carrcap = (carrcap * (long) youmonst.data->cwt / WT_HUMAN);
3278 if (Levitation || Is_airlevel(&u.uz) /* pugh@cornell */
3279 || (u.usteed && strongmonst(u.usteed->data)))
3280 carrcap = MAX_CARR_CAP;
3282 if (carrcap > MAX_CARR_CAP)
3283 carrcap = MAX_CARR_CAP;
3285 if (EWounded_legs & LEFT_SIDE)
3287 if (EWounded_legs & RIGHT_SIDE)
3293 return (int) carrcap;
3296 static int wc; /* current weight_cap(); valid after call to inv_weight() */
3298 /* returns how far beyond the normal capacity the player is currently. */
3299 /* inv_weight() is negative if the player is below normal capacity. */
3303 register struct obj *otmp = invent;
3304 register int wt = 0;
3307 if (otmp->oclass == COIN_CLASS)
3308 wt += (int) (((long) otmp->quan + 50L) / 100L);
3309 else if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data))
3318 * Returns 0 if below normal capacity, or the number of "capacity units"
3319 * over the normal capacity the player is loaded. Max is 5.
3322 calc_capacity(xtra_wt)
3325 int cap, wt = inv_weight() + xtra_wt;
3328 return UNENCUMBERED;
3331 cap = (wt * 2 / wc) + 1;
3332 return min(cap, OVERLOADED);
3338 return calc_capacity(0);
3344 int wt = inv_weight();
3346 return (wt - (2 * wc));
3353 if (near_capacity() >= EXT_ENCUMBER) {
3358 You_cant("do that while carrying so much stuff.");
3360 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");
3370 register struct obj *otmp = invent;
3371 register int ct = 0;
3374 if (incl_gold || otmp->invlet != GOLD_SYM)
3381 /* Counts the money in an object chain. */
3382 /* Intended use is for your or some monsters inventory, */
3383 /* now that u.gold/m.gold is gone.*/
3384 /* Counting money in a container might be possible too. */
3390 /* Must change when silver & copper is implemented: */
3391 if (otmp->oclass == COIN_CLASS)