1 /* NetHack 3.6 teleport.c $NHDT-Date: 1446887535 2015/11/07 09:12:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.62 $ */
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 STATIC_DCL boolean FDECL(tele_jump_ok, (int, int, int, int));
13 STATIC_DCL boolean FDECL(teleok, (int, int, BOOLEAN_P));
14 STATIC_DCL void NDECL(vault_tele);
15 STATIC_DCL boolean FDECL(rloc_pos_ok, (int, int, struct monst *));
16 STATIC_DCL void FDECL(mvault_tele, (struct monst *));
18 /* non-null when teleporting via having read this scroll */
19 STATIC_VAR struct obj *telescroll = 0;
22 * Is (x,y) a good position of mtmp? If mtmp is NULL, then is (x,y) good
25 * This function will only look at mtmp->mdat, so makemon, mplayer, etc can
26 * call it to generate new monster positions with fake monster structures.
29 goodpos(x, y, mtmp, gpflags)
34 struct permonst *mdat = (struct permonst *) 0;
35 boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0);
40 /* in many cases, we're trying to create a new monster, which
41 * can't go on top of the player or any existing monster.
42 * however, occasionally we are relocating engravings or objects,
43 * which could be co-located and thus get restricted a bit too much.
46 if (mtmp != &youmonst && x == u.ux && y == u.uy
47 && (!u.usteed || mtmp != u.usteed))
51 struct monst *mtmp2 = m_at(x, y);
53 /* Be careful with long worms. A monster may be placed back in
54 * its own location. Normally, if m_at() returns the same monster
55 * that we're trying to place, the monster is being placed in its
56 * own location. However, that is not correct for worm segments,
57 * because all the segments of the worm return the same m_at().
58 * Actually we overdo the check a little bit--a worm can't be placed
59 * in its own location, period. If we just checked for mtmp->mx
60 * != x || mtmp->my != y, we'd miss the case where we're called
61 * to place the worm segment and the worm's head is at x,y.
63 if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
67 if (is_pool(x, y) && !ignorewater) {
68 if (mtmp == &youmonst)
69 return (Levitation || Flying || Wwalking || Swimming
72 return (is_floater(mdat) || is_flyer(mdat) || is_swimmer(mdat)
74 } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
76 } else if (is_lava(x, y)) {
77 if (mtmp == &youmonst)
78 return (Levitation || Flying
79 || (Fire_resistance && Wwalking && uarmf
80 && uarmf->oerodeproof)
81 || (Upolyd && likes_lava(youmonst.data)));
83 return (is_floater(mdat) || is_flyer(mdat)
86 if (passes_walls(mdat) && may_passwall(x, y))
88 if (amorphous(mdat) && closed_door(x, y))
91 if (!accessible(x, y)) {
92 if (!(is_pool(x, y) && ignorewater))
96 if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
104 * Attempt to find a good place for the given monster type in the closest
105 * position to (xx,yy). Do so in successive square rings around (xx,yy).
106 * If there is more than one valid position in the ring, choose one randomly.
107 * Return TRUE and the position chosen when successful, FALSE otherwise.
110 enexto(cc, xx, yy, mdat)
112 register xchar xx, yy;
113 struct permonst *mdat;
115 return enexto_core(cc, xx, yy, mdat, 0);
119 enexto_core(cc, xx, yy, mdat, entflags)
121 register xchar xx, yy;
122 struct permonst *mdat;
126 coord good[MAX_GOOD], *good_ptr;
128 int xmin, xmax, ymin, ymax;
129 struct monst fakemon; /* dummy monster */
132 debugpline0("enexto() called with null mdat");
133 /* default to player's original monster type */
134 mdat = &mons[u.umonster];
136 fakemon.data = mdat; /* set up for goodpos */
140 * Walk around the border of the square with center (xx,yy) and
141 * radius range. Stop when we find at least one valid position.
144 xmin = max(1, xx - range);
145 xmax = min(COLNO - 1, xx + range);
146 ymin = max(0, yy - range);
147 ymax = min(ROWNO - 1, yy + range);
149 for (x = xmin; x <= xmax; x++)
150 if (goodpos(x, ymin, &fakemon, entflags)) {
153 /* beware of accessing beyond segment boundaries.. */
154 if (good_ptr++ == &good[MAX_GOOD - 1])
157 for (x = xmin; x <= xmax; x++)
158 if (goodpos(x, ymax, &fakemon, entflags)) {
161 /* beware of accessing beyond segment boundaries.. */
162 if (good_ptr++ == &good[MAX_GOOD - 1])
165 for (y = ymin + 1; y < ymax; y++)
166 if (goodpos(xmin, y, &fakemon, entflags)) {
169 /* beware of accessing beyond segment boundaries.. */
170 if (good_ptr++ == &good[MAX_GOOD - 1])
173 for (y = ymin + 1; y < ymax; y++)
174 if (goodpos(xmax, y, &fakemon, entflags)) {
177 /* beware of accessing beyond segment boundaries.. */
178 if (good_ptr++ == &good[MAX_GOOD - 1])
183 /* return if we've grown too big (nothing is valid) */
184 if (range > ROWNO && range > COLNO)
186 } while (good_ptr == good);
189 i = rn2((int) (good_ptr - good));
196 * Check for restricted areas present in some special levels. (This might
197 * need to be augmented to allow deliberate passage in wizard mode, but
198 * only for explicitly chosen destinations.)
201 tele_jump_ok(x1, y1, x2, y2)
204 if (dndest.nlx > 0) {
205 /* if inside a restricted region, can't teleport outside */
206 if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
208 && !within_bounded_area(x2, y2, dndest.nlx, dndest.nly,
209 dndest.nhx, dndest.nhy))
211 /* and if outside, can't teleport inside */
212 if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
214 && within_bounded_area(x2, y2, dndest.nlx, dndest.nly, dndest.nhx,
218 if (updest.nlx > 0) { /* ditto */
219 if (within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
221 && !within_bounded_area(x2, y2, updest.nlx, updest.nly,
222 updest.nhx, updest.nhy))
224 if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
226 && within_bounded_area(x2, y2, updest.nlx, updest.nly, updest.nhx,
238 if (!trapok && t_at(x, y))
240 if (!goodpos(x, y, &youmonst, 0))
242 if (!tele_jump_ok(u.ux, u.uy, x, y))
244 if (!in_out_region(x, y))
250 teleds(nux, nuy, allow_drag)
251 register int nux, nuy;
254 boolean ball_active, ball_still_in_range;
256 if (u.utraptype == TT_BURIEDBALL) {
258 buried_ball_to_punishment();
260 ball_active = (Punished && uball->where != OBJ_FREE),
261 ball_still_in_range = FALSE;
263 /* If they have to move the ball, then drag if allow_drag is true;
264 * otherwise they are teleporting, so unplacebc().
265 * If they don't have to move the ball, then always "drag" whether or
266 * not allow_drag is true, because we are calling that function, not
267 * to drag, but to move the chain. *However* there are some dumb
270 * _X move east -----> X_
272 * These are permissible if teleporting, but not if dragging. As a
273 * result, drag_ball() needs to know about allow_drag and might end
274 * up dragging the ball anyway. Also, drag_ball() might find that
275 * dragging the ball is completely impossible (ball in range but there's
276 * rock in the way), in which case it teleports the ball on its own.
279 if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2)
280 ball_still_in_range = TRUE; /* don't have to move the ball */
282 /* have to move the ball */
283 if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
284 /* we should not have dist > 1 and allow_drag at the same
285 * time, but just in case, we must then revert to teleport.
297 if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
298 /* mimics stop being unnoticed */
299 youmonst.m_ap_type = M_AP_NOTHING;
303 u.uswldtim = u.uswallow = 0;
304 if (Punished && !ball_active) {
305 /* ensure ball placement, like unstuck */
312 if (ball_still_in_range || allow_drag) {
314 xchar ballx, bally, chainx, chainy;
317 if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, &chainx,
318 &chainy, &cause_delay, allow_drag))
319 move_bc(0, bc_control, ballx, bally, chainx, chainy);
322 /* must set u.ux, u.uy after drag_ball(), which may need to know
323 the old position if allow_drag is true... */
324 u_on_newpos(nux, nuy); /* set u.<x,y>, usteed-><mx,my>; cliparound() */
325 fill_pit(u.ux0, u.uy0);
327 if (!ball_still_in_range && !allow_drag)
330 initrack(); /* teleports mess up tracking monsters without this */
331 update_player_regions();
333 * Make sure the hero disappears from the old location. This will
334 * not happen if she is teleported within sight of her previous
335 * location. Force a full vision recalculation because the hero
336 * is now in a new location.
338 newsym(u.ux0, u.uy0);
340 vision_full_recalc = 1;
342 vision_recalc(0); /* vision before effects */
344 /* when teleporting by scroll, we need to handle discovery
345 now before getting feedback about any objects at our
346 destination since we might land on another such scroll */
347 if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0))
348 learnscroll(telescroll);
350 telescroll = 0; /* no discovery by scrolltele()'s caller */
353 invocation_message();
357 safe_teleds(allow_drag)
360 register int nux, nuy, tcnt = 0;
363 nux = rnd(COLNO - 1);
365 } while (!teleok(nux, nuy, (boolean) (tcnt > 200)) && ++tcnt <= 400);
368 teleds(nux, nuy, allow_drag);
377 register struct mkroom *croom = search_special(VAULT);
380 if (croom && somexy(croom, &c) && teleok(c.x, c.y, FALSE)) {
381 teleds(c.x, c.y, FALSE);
388 teleport_pet(mtmp, force_it)
389 register struct monst *mtmp;
392 register struct obj *otmp;
394 if (mtmp == u.usteed)
397 if (mtmp->mleashed) {
398 otmp = get_mleash(mtmp);
400 impossible("%s is leashed, without a leash.", Monnam(mtmp));
403 if (otmp->cursed && !force_it) {
408 Your("leash goes slack.");
410 Your("
\95R
\82Í
\82½
\82é
\82ñ
\82¾
\81D");
412 m_unleash(mtmp, FALSE);
419 /* teleport the hero via some method other than scroll of teleport */
423 (void) scrolltele((struct obj *) 0);
426 /* teleport the hero; return true if scroll of teleportation should become
427 discovered; teleds() will usually do the actual discovery, since the
428 outcome sometimes depends upon destination and discovery needs to be
429 performed before arrival, in case we land on another teleport scroll */
435 boolean result = FALSE; /* don't learn scroll */
437 /* Disable teleportation in stronghold && Vlad's Tower */
438 if (level.flags.noteleport) {
441 pline("A mysterious force prevents you from teleporting!");
443 pline("
\8aï
\96
\82È
\97Í
\82ª
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I");
448 /* don't show trap if "Sorry..." */
450 make_blinded(0L, FALSE);
452 if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
454 You_feel("disoriented for a moment.");
456 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
457 if (!wizard || yn("Override?") != 'y')
460 if ((Teleport_control && !Stunned) || wizard) {
463 pline("Being unconscious, you cannot control your teleport.");
465 pline("
\88Ó
\8e¯
\82ª
\82È
\82¢
\82Ì
\82Å
\81C
\82 \82È
\82½
\82Í
\8fu
\8aÔ
\88Ú
\93®
\82ð
\90§
\8cä
\82Å
\82«
\82È
\82¢
\81D");
467 #if 0 /*JP*//*
\8eå
\8cê
\82ð
\8fÈ
\97ª
\82µ
\82Ä
\8aÈ
\97ª
\89»*/
470 Strcpy(whobuf, "you");
472 Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
473 pline("To what position do %s want to be teleported?", whobuf);
475 pline("
\82Ç
\82Ì
\88Ê
\92u
\82É
\8fu
\8aÔ
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
480 if (getpos(&cc, TRUE, "the desired position") < 0)
482 if (getpos(&cc, TRUE, "
\88Ú
\93®
\82µ
\82½
\82¢
\8fê
\8f\8a") < 0)
483 return TRUE; /* abort */
484 /* possible extensions: introduce a small error if
485 magic power is low; allow transfer to solid rock */
486 if (teleok(cc.x, cc.y, FALSE)) {
487 /* for scroll, discover it regardless of destination */
490 teleds(cc.x, cc.y, FALSE);
496 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
499 } else if (scroll && scroll->blessed) {
500 /* (this used to be handled in seffects()) */
501 if (yn("Do you wish to teleport?") == 'n')
507 (void) safe_teleds(FALSE);
508 /* teleds() will leave telescroll intact iff random destination
509 is far enough away for scroll discovery to be warranted */
512 telescroll = 0; /* reset */
520 boolean trap_once = FALSE;
522 trap = t_at(u.ux, u.uy);
523 if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
527 trap_once = trap->once; /* trap may get deleted, save this */
530 pline("This is a vault teleport, usable once only.");
532 pline("
\88ê
\93x
\82©
\82¬
\82è
\82Ì
\91q
\8cÉ
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82¾
\81D");
534 if (yn("Jump in?") == 'n')
536 if (yn("
\94ò
\82Ñ
\8d\9e\82Þ
\81H") == 'n')
545 You("%s onto the teleportation trap.",
546 locomotion(youmonst.data, "jump"));
548 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82É
\94ò
\82Ñ
\82±
\82ñ
\82¾
\81D");
552 boolean castit = FALSE;
553 register int sp_no = 0, energy = 0;
555 if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
556 && !can_teleport(youmonst.data))) {
557 /* Try to use teleport away spell. */
558 if (objects[SPE_TELEPORT_AWAY].oc_name_known && !Confusion)
559 for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
560 if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) {
568 You("don't know that spell.");
570 You("
\82»
\82ñ
\82È
\96\82\96@
\82Í
\92m
\82ç
\82È
\82¢
\81D");
573 You("are not able to teleport at will.");
575 You("
\8e©
\95ª
\82Ì
\88Ó
\8ev
\82Å
\8fu
\8aÔ
\88Ú
\93®
\82Å
\82«
\82È
\82¢
\81D");
581 if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
584 You("lack the strength %s.",
585 castit ? "for a teleport spell" : "to teleport");
587 You("%s
\82¾
\82¯
\82Ì
\97Í
\82ª
\82È
\82¢
\81D",
588 castit ? "
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é" : "
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é");
594 energy = objects[SPE_TELEPORT_AWAY].oc_level * 7 / 2 - 2;
595 if (u.uen <= energy) {
600 You("lack the energy %s.",
601 castit ? "for a teleport spell" : "to teleport");
603 You("%s
\82¾
\82¯
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\82È
\82¢
\81D",
604 castit ? "
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é" : "
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é");
612 "Your concentration falters from carrying so much."))
614 "
\91ò
\8eR
\82à
\82Ì
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\8fW
\92\86\82Å
\82«
\82È
\82¢
\81D"))
618 exercise(A_WIS, TRUE);
619 if (spelleffects(sp_no, TRUE))
630 if (trap && trap_once)
636 You1(shudder_for_moment);
649 const char *escape_by_flying = 0; /* when surviving dest of -N */
651 boolean force_dest = FALSE;
653 if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
656 You_feel("very disoriented for a moment.");
658 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
661 if ((Teleport_control && !Stunned) || wizard) {
666 Strcpy(qbuf, "To what level do you want to teleport?");
668 Strcpy(qbuf, "
\89½
\8aK
\82É
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
672 Strcat(qbuf, " [type a number or ? for a menu]");
675 Strcat(qbuf, " [type a number]");
677 Strcat(qbuf, " [
\90\94\8e\9a\82ð
\82¢
\82ê
\82Ä
\82Ë]");
680 if (!strcmp(buf, "\033")) { /* cancelled */
681 if (Confusion && rnl(5)) {
685 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
686 goto random_levtport;
689 } else if (!strcmp(buf, "*")) {
690 goto random_levtport;
691 } else if (Confusion && rnl(5)) {
695 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
696 goto random_levtport;
698 if (wizard && !strcmp(buf, "?")) {
702 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
706 newlevel.dnum = destdnum;
707 newlevel.dlevel = destlev;
708 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
712 && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
714 /* ordinarily we'd use hold_another_object()
715 for something like this, but we don't want
716 fumbling or already full pack to interfere */
718 prinv("Endgame prerequisite:", amu, 0L);
722 } else if ((newlev = lev_by_name(buf)) == 0)
724 } while (!newlev && !digit(buf[0])
725 && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
727 /* no dungeon escape via this route */
730 goto random_levtport;
732 if (ynq("Go to Nowhere. Are you sure?") != 'y')
734 if (ynq("
\82Ç
\82±
\82Æ
\82à
\92m
\82ê
\82Ê
\8fê
\8f\8a\82É
\8ds
\82«
\82Ü
\82·
\81H
\82æ
\82ë
\82µ
\82¢
\82Å
\82·
\82©
\81H") != 'y')
737 You("%s in agony as your body begins to warp...",
738 is_silent(youmonst.data) ? "writhe" : "scream");
740 You("
\91Ì
\82ª
\88Ú
\93®
\82µ
\82Í
\82¶
\82ß
\82é
\82Æ
\81C
\8bê
\82µ
\82Ý%s
\81D
\81D
\81D",
741 is_silent(youmonst.data) ? "
\82Å
\90g
\82à
\82¾
\82¦
\82µ
\82½" : "
\82Ì
\82 \82¦
\82¬
\90º
\82ð
\8fo
\82µ
\82½");
743 display_nhwindow(WIN_MESSAGE, FALSE);
745 You("cease to exist.");
747 Your("
\91¶
\8dÝ
\82Í
\8fÁ
\96Å
\82µ
\82½
\81D");
750 Your("possessions land on the %s with a thud.",
752 Your("
\8e\9d\82¿
\82à
\82Ì
\82Í
\83h
\83T
\83b
\82Æ%s
\82É
\97\8e\82¿
\82½
\81D",
753 surface(u.ux, u.uy));
754 killer.format = NO_KILLER_PREFIX;
756 Strcpy(killer.name, "committed suicide");
758 Strcpy(killer.name, "
\8e©
\8eE
\82µ
\82½");
761 pline("An energized cloud of dust begins to coalesce.");
763 pline("
\83G
\83l
\83\8b\83M
\81[
\82ð
\82à
\82Á
\82½
\82Ù
\82±
\82è
\82Ì
\89Q
\82ª
\8c\8b\8d\87\82µ
\82Í
\82¶
\82ß
\82½
\81D");
765 Your("body rematerializes%s.",
766 invent ? ", and you gather up all your possessions" : "");
768 Your("
\91Ì
\82Í
\8dÄ
\82Ñ
\8eÀ
\91Ì
\89»
\82µ
\82½
\81D%s",
769 invent ? "
\82»
\82µ
\82Ä
\91S
\82Ä
\82Ì
\8e\9d\82¿
\95¨
\82ð
\8fE
\82¢
\8fã
\82°
\82½
\81D" : "");
774 /* if in Knox and the requested level > 0, stay put.
775 * we let negative values requests fall into the "heaven" loop.
777 if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
778 You1(shudder_for_moment);
781 /* if in Quest, the player sees "Home 1", etc., on the status
782 * line, instead of the logical depth of the level. controlled
783 * level teleport request is likely to be relativized to the
784 * status line, and consequently it should be incremented to
785 * the value of the logical depth of the target level.
787 * we let negative values requests fall into the "heaven" loop.
789 if (In_quest(&u.uz) && newlev > 0)
790 newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
791 } else { /* involuntary level tele */
793 newlev = random_teleport_level();
794 if (newlev == depth(&u.uz)) {
795 You1(shudder_for_moment);
800 if (u.utrap && u.utraptype == TT_BURIEDBALL)
801 buried_ball_to_punishment();
803 if (!next_to_u() && !force_dest) {
804 You1(shudder_for_moment);
807 if (In_endgame(&u.uz)) { /* must already be wizard */
808 int llimit = dunlevs_in_dungeon(&u.uz);
810 if (newlev >= 0 || newlev <= -llimit) {
812 You_cant("get there from here.");
814 You("
\82»
\82±
\82É
\82Í
\8ds
\82¯
\82È
\82¢
\81D");
817 newlevel.dnum = u.uz.dnum;
818 newlevel.dlevel = llimit + newlev;
819 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
823 killer.name[0] = 0; /* still alive, so far... */
825 if (newlev < 0 && !force_dest) {
827 /* take unpaid inventory items off of shop bills */
828 in_mklev = TRUE; /* suppress map update */
829 u_left_shop(u.ushops0, TRUE);
830 /* you're now effectively out of the shop */
831 *u.ushops0 = *u.ushops = '\0';
836 You("arrive in heaven.");
838 You("
\93V
\8d\91\82É
\92H
\82è
\82Â
\82¢
\82½
\81D");
840 verbalize("Thou art early, but we'll admit thee.");
842 verbalize("
\93ð
\81C
\8e\80\82Ê
\82É
\82Í
\91\81\82·
\82¬
\82é
\82ª
\82»
\82ê
\82à
\82æ
\82©
\82ë
\82¤
\81D");
843 killer.format = NO_KILLER_PREFIX;
845 Strcpy(killer.name, "went to heaven prematurely");
847 Strcpy(killer.name, "
\8eá
\82
\82µ
\82Ä
\93V
\8d\91\82É
\8ds
\82Á
\82½");
848 } else if (newlev == -9) {
850 You_feel("deliriously happy. ");
852 You("
\8b¶
\82Á
\82½
\82æ
\82¤
\82È
\8dK
\82¹
\82ð
\8a´
\82¶
\82½
\81D");
854 pline("(In fact, you're on Cloud 9!) ");
856 pline("(
\96{
\93\96\82É
\8bê
\82ð
\8fæ
\82è
\89z
\82¦
\82½
\8fê
\8f\8a\82É
\82¢
\82é
\81I) ");
857 display_nhwindow(WIN_MESSAGE, FALSE);
860 You("are now high above the clouds...");
862 You("
\89_
\82Ì
\97y
\82©
\8fã
\82É
\82¢
\82é
\81D
\81D
\81D");
864 if (killer.name[0]) {
865 ; /* arrival in heaven is pending */
866 } else if (Levitation) {
868 escape_by_flying = "float gently down to earth";
870 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
873 escape_by_flying = "fly down to the ground";
875 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
878 pline("Unfortunately, you don't know how to fly.");
880 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í
\94ò
\82Ñ
\82©
\82½
\82ð
\92m
\82ç
\82È
\82¢
\81D");
882 You("plummet a few thousand feet to your death.");
884 pline("
\90\94\90ç
\83t
\83B
\81[
\83g
\82Ì
\8e\80\82Ì
\83_
\83C
\83r
\83\93\83O
\82¾
\81I");
887 "teleported out of the dungeon and fell to %s death",
889 killer.format = NO_KILLER_PREFIX;
891 Strcpy(killer.name, "
\96À
\8b{
\82ð
\94ò
\82Ñ
\82¾
\82µ
\83_
\83C
\83r
\83\93\83O
\82µ
\82Ä");
892 killer.format = KILLED_BY;
897 if (killer.name[0]) { /* the chosen destination was not survivable */
900 /* set specific death location; this also suppresses bones */
901 lsav = u.uz; /* save current level, see below */
902 u.uz.dnum = 0; /* main dungeon */
903 u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */
905 /* can only get here via life-saving (or declining to die in
906 explore|debug mode); the hero has now left the dungeon... */
908 escape_by_flying = "find yourself back on the surface";
910 escape_by_flying = "
\8bC
\82ª
\82Â
\82¢
\82½
\82ç
\92n
\8fã
\82É
\96ß
\82Á
\82Ä
\82¢
\82½";
911 u.uz = lsav; /* restore u.uz so escape code works */
914 /* calls done(ESCAPED) if newlevel==0 */
915 if (escape_by_flying) {
917 You("%s.", escape_by_flying);
919 You("%s
\81D", escape_by_flying);
920 newlevel.dnum = 0; /* specify main dungeon */
921 newlevel.dlevel = 0; /* escape the dungeon */
922 /* [dlevel used to be set to 1, but it doesn't make sense to
923 teleport out of the dungeon and float or fly down to the
924 surface but then actually arrive back inside the dungeon] */
925 } else if (u.uz.dnum == medusa_level.dnum
926 && newlev >= dungeons[u.uz.dnum].depth_start
927 + dunlevs_in_dungeon(&u.uz)) {
928 if (!(wizard && force_dest))
929 find_hell(&newlevel);
931 /* if invocation did not yet occur, teleporting into
932 * the last level of Gehennom is forbidden.
934 if (!wizard && Inhell && !u.uevent.invoked
935 && newlev >= (dungeons[u.uz.dnum].depth_start
936 + dunlevs_in_dungeon(&u.uz) - 1)) {
937 newlev = dungeons[u.uz.dnum].depth_start
938 + dunlevs_in_dungeon(&u.uz) - 2;
942 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
944 /* no teleporting out of quest dungeon */
945 if (In_quest(&u.uz) && newlev < depth(&qstart_level))
946 newlev = depth(&qstart_level);
947 /* the player thinks of levels purely in logical terms, so
948 * we must translate newlev to a number relative to the
951 if (!(wizard && force_dest))
952 get_level(&newlevel, newlev);
954 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
955 /* in case player just read a scroll and is about to be asked to
956 call it something, we can't defer until the end of the turn */
957 if (u.utotype && !context.mon_moving)
963 register struct trap *ttmp;
965 struct d_level target_level;
967 if (u.utrap && u.utraptype == TT_BURIEDBALL)
968 buried_ball_to_punishment();
971 You1(shudder_for_moment);
975 /* if landed from another portal, do nothing */
976 /* problem: level teleport landing escapes the check */
977 if (!on_level(&u.uz, &u.uz0))
981 You("activated a magic portal!");
983 pline("
\96\82\96@
\82Ì
\93ü
\8cû
\82ª
\8dì
\93®
\82µ
\82½
\81I");
985 /* prevent the poor shnook, whose amulet was stolen while in
986 * the endgame, from accidently triggering the portal to the
987 * next level, and thus losing the game
989 if (In_endgame(&u.uz) && !u.uhave.amulet) {
991 You_feel("dizzy for a moment, but nothing happens...");
993 You("
\88ê
\8fu
\82ß
\82Ü
\82¢
\82ð
\8a´
\82¶
\82½
\81C
\82µ
\82©
\82µ
\89½
\82à
\8bN
\82«
\82È
\82©
\82Á
\82½
\81D
\81D
\81D");
997 target_level = ttmp->dst;
998 schedule_goto(&target_level, FALSE, FALSE, 1,
1000 "You feel dizzy for a moment, but the sensation passes.",
1002 "
\88ê
\8fu
\82ß
\82Ü
\82¢
\82ð
\8a´
\82¶
\82½
\81C
\82µ
\82©
\82µ
\82»
\82Ì
\8a´
\8ao
\82Í
\8fÁ
\82¦
\82½
\81D",
1010 if (In_endgame(&u.uz) || Antimagic) {
1012 shieldeff(u.ux, u.uy);
1014 You_feel("a wrenching sensation.");
1016 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1017 } else if (!next_to_u()) {
1018 You1(shudder_for_moment);
1019 } else if (trap->once) {
1021 newsym(u.ux, u.uy); /* get rid of trap symbol */
1028 level_tele_trap(trap)
1032 You("%s onto a level teleport trap!",
1033 Levitation ? (const char *) "float"
1034 : locomotion(youmonst.data, "step"));
1036 You("
\95Ê
\82Ì
\8aK
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82ð%s
\81I",
1037 Levitation ? (const char *) "
\8c©
\89º
\82ë
\82µ
\82½"
1038 : jpast(locomotion(youmonst.data, "
\93¥
\82Þ")));
1041 shieldeff(u.ux, u.uy);
1043 if (Antimagic || In_endgame(&u.uz)) {
1045 You_feel("a wrenching sensation.");
1047 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1052 You("are momentarily blinded by a flash of light.");
1054 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81D");
1057 You("are momentarily disoriented.");
1059 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D");
1061 newsym(u.ux, u.uy); /* get rid of trap symbol */
1065 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1067 rloc_pos_ok(x, y, mtmp)
1068 register int x, y; /* coordinates of candidate location */
1071 register int xx, yy;
1073 if (!goodpos(x, y, mtmp, 0))
1076 * Check for restricted areas present in some special levels.
1078 * `xx' is current column; if 0, then `yy' will contain flag bits
1079 * rather than row: bit #0 set => moving upwards; bit #1 set =>
1080 * inside the Wizard's tower.
1085 /* no current location (migrating monster arrival) */
1086 if (dndest.nlx && On_W_tower_level(&u.uz))
1087 return (((yy & 2) != 0)
1088 /* inside xor not within */
1089 ^ !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1090 dndest.nhx, dndest.nhy));
1091 if (updest.lx && (yy & 1) != 0) /* moving up */
1092 return (within_bounded_area(x, y, updest.lx, updest.ly,
1093 updest.hx, updest.hy)
1095 || !within_bounded_area(x, y, updest.nlx, updest.nly,
1096 updest.nhx, updest.nhy)));
1097 if (dndest.lx && (yy & 1) == 0) /* moving down */
1098 return (within_bounded_area(x, y, dndest.lx, dndest.ly,
1099 dndest.hx, dndest.hy)
1101 || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1102 dndest.nhx, dndest.nhy)));
1104 /* [try to] prevent a shopkeeper or temple priest from being
1105 sent out of his room (caller might resort to goodpos() if
1106 we report failure here, so this isn't full prevention) */
1107 if (mtmp->isshk && inhishop(mtmp)) {
1108 if (levl[x][y].roomno != ESHK(mtmp)->shoproom)
1110 } else if (mtmp->ispriest && inhistemple(mtmp)) {
1111 if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1114 /* current location is <xx,yy> */
1115 if (!tele_jump_ok(xx, yy, x, y))
1125 * Pulls a monster from its current position and places a monster at
1126 * a new x and y. If oldx is 0, then the monster was not in the
1128 * array. However, if oldx is 0, oldy may still have a value because mtmp is
1130 * migrating_mon. Worm tails are always placed randomly around the head of
1138 register int oldx = mtmp->mx, oldy = mtmp->my;
1139 boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1141 if (x == mtmp->mx && y == mtmp->my) /* that was easy */
1144 if (oldx) { /* "pick up" monster */
1148 remove_monster(oldx, oldy);
1149 newsym(oldx, oldy); /* update old location */
1153 place_monster(mtmp, x, y); /* put monster down */
1154 update_monster_region(mtmp);
1156 if (mtmp->wormno) /* now put down tail */
1157 place_worm_tail_randomly(mtmp, x, y);
1159 if (u.ustuck == mtmp) {
1168 newsym(x, y); /* update new location */
1169 set_apparxy(mtmp); /* orient monster */
1171 /* shopkeepers will only teleport if you zap them with a wand of
1172 teleportation or if they've been transformed into a jumpy monster;
1173 the latter only happens if you've attacked them with polymorph */
1174 if (resident_shk && !inhishop(mtmp))
1175 make_angry_shk(mtmp, oldx, oldy);
1178 /* place a monster at a random location, typically due to teleport */
1179 /* return TRUE if successful, FALSE if not */
1181 rloc(mtmp, suppress_impossible)
1182 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1183 boolean suppress_impossible;
1185 register int x, y, trycount;
1187 if (mtmp == u.usteed) {
1192 if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */
1193 if (!In_W_tower(u.ux, u.uy, &u.uz))
1194 x = xupstair, y = yupstair;
1195 else if (!xdnladder) /* bottom level of tower */
1196 x = xupladder, y = yupladder;
1198 x = xdnladder, y = ydnladder;
1199 /* if the wiz teleports away to heal, try the up staircase,
1200 to block the player's escaping before he's healed
1201 (deliberately use `goodpos' rather than `rloc_pos_ok' here) */
1202 if (goodpos(x, y, mtmp, 0))
1208 x = rn1(COLNO - 3, 2);
1210 if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1211 : goodpos(x, y, mtmp, 0))
1213 } while (++trycount < 1000);
1215 /* last ditch attempt to find a good place */
1216 for (x = 2; x < COLNO - 1; x++)
1217 for (y = 0; y < ROWNO; y++)
1218 if (goodpos(x, y, mtmp, 0))
1221 /* level either full of monsters or somehow faulty */
1222 if (!suppress_impossible)
1223 impossible("rloc(): couldn't relocate monster");
1227 rloc_to(mtmp, x, y);
1235 register struct mkroom *croom = search_special(VAULT);
1238 if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1239 rloc_to(mtmp, c.x, c.y);
1242 (void) rloc(mtmp, TRUE);
1249 if (level.flags.noteleport) {
1252 pline("A mysterious force prevents %s from teleporting!",
1255 pline("
\8aï
\96
\82È
\97Í
\82ª%s
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I",
1264 mtele_trap(mtmp, trap, in_sight)
1271 if (tele_restrict(mtmp))
1273 if (teleport_pet(mtmp, FALSE)) {
1274 /* save name with pre-movement visibility */
1275 monname = Monnam(mtmp);
1277 /* Note: don't remove the trap if a vault. Other-
1278 * wise the monster will be stuck there, since
1279 * the guard isn't going to come for it...
1284 (void) rloc(mtmp, TRUE);
1287 if (canseemon(mtmp))
1289 pline("%s seems disoriented.", monname);
1291 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D", monname);
1294 pline("%s suddenly disappears!", monname);
1296 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", monname);
1302 /* return 0 if still on level, 3 if not */
1304 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1310 int tt = trap->ttyp;
1311 struct permonst *mptr = mtmp->data;
1313 if (mtmp == u.ustuck) /* probably a vortex */
1314 return 0; /* temporary? kludge */
1315 if (teleport_pet(mtmp, force_it)) {
1317 int migrate_typ = MIGR_RANDOM;
1319 if ((tt == HOLE || tt == TRAPDOOR)) {
1320 if (Is_stronghold(&u.uz)) {
1321 assign_level(&tolevel, &valley_level);
1322 } else if (Is_botlevel(&u.uz)) {
1323 if (in_sight && trap->tseen)
1325 pline("%s avoids the %s.", Monnam(mtmp),
1326 (tt == HOLE) ? "hole" : "trap");
1328 pline("%s
\82Í%s
\82ð
\89ñ
\94ð
\82µ
\82½
\81D", Monnam(mtmp),
1329 (tt == HOLE) ? "
\8c\8a" : "ã©");
1333 get_level(&tolevel, depth(&u.uz) + 1);
1335 } else if (tt == MAGIC_PORTAL) {
1336 if (In_endgame(&u.uz)
1337 && (mon_has_amulet(mtmp) || is_home_elemental(mptr))) {
1338 if (in_sight && mptr->mlet != S_ELEMENTAL) {
1340 pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1342 pline("%s
\82ª
\88ê
\8fu
\8bP
\82¢
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81D", Monnam(mtmp));
1347 assign_level(&tolevel, &trap->dst);
1348 migrate_typ = MIGR_PORTAL;
1350 } else { /* (tt == LEVEL_TELEP) */
1353 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)) {
1356 pline("%s seems very disoriented for a moment.",
1358 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
1362 nlev = random_teleport_level();
1363 if (nlev == depth(&u.uz)) {
1366 pline("%s shudders for a moment.", Monnam(mtmp));
1368 pline("%s
\82Í
\88ê
\8fu
\90k
\82¦
\82½
\81D", Monnam(mtmp));
1371 get_level(&tolevel, nlev);
1376 pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1378 pline("
\93Ë
\91R%s
\82ª
\8e\8b\8aE
\82©
\82ç
\8fÁ
\82¦
\82½
\81D", mon_nam(mtmp));
1381 migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1382 return 3; /* no longer on this level */
1387 /* place object randomly, returns False if it's gone (eg broken) */
1390 register struct obj *obj;
1392 register xchar tx, ty, otx, oty;
1393 boolean restricted_fall;
1394 int try_limit = 4000;
1396 if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1397 if (revive_corpse(obj))
1401 obj_extract_self(obj);
1404 restricted_fall = (otx == 0 && dndest.lx);
1406 tx = rn1(COLNO - 3, 2);
1410 } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1412 && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1413 dndest.hx, dndest.hy)
1415 && within_bounded_area(tx, ty,
1416 dndest.nlx, dndest.nly,
1417 dndest.nhx, dndest.nhy))))
1418 /* on the Wizard Tower levels, objects inside should
1419 stay inside and objects outside should stay outside */
1420 || (dndest.nlx && On_W_tower_level(&u.uz)
1421 && within_bounded_area(tx, ty, dndest.nlx, dndest.nly,
1422 dndest.nhx, dndest.nhy)
1423 != within_bounded_area(otx, oty, dndest.nlx, dndest.nly,
1424 dndest.nhx, dndest.nhy)));
1427 if (flooreffects(obj, tx, ty, "fall")) {
1429 if (flooreffects(obj, tx, ty, "
\97\8e\82¿
\82é")) {
1431 } else if (otx == 0 && oty == 0) {
1432 ; /* fell through a trap door; no update of old loc needed */
1434 if (costly_spot(otx, oty)
1435 && (!costly_spot(tx, ty)
1436 || !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) {
1437 if (costly_spot(u.ux, u.uy)
1438 && index(u.urooms, *in_rooms(otx, oty, 0)))
1439 addtobill(obj, FALSE, FALSE, FALSE);
1441 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1443 newsym(otx, oty); /* update old location */
1445 place_object(obj, tx, ty);
1450 /* Returns an absolute depth */
1452 random_teleport_level()
1454 int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1456 /* [the endgame case can only occur in wizard mode] */
1457 if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1460 /* What I really want to do is as follows:
1461 * -- If in a dungeon that goes down, the new level is to be restricted
1462 * to [top of parent, bottom of current dungeon]
1463 * -- If in a dungeon that goes up, the new level is to be restricted
1464 * to [top of current dungeon, bottom of parent]
1465 * -- If in a quest dungeon or similar dungeon entered by portals,
1466 * the new level is to be restricted to [top of current dungeon,
1467 * bottom of current dungeon]
1468 * The current behavior is not as sophisticated as that ideal, but is
1469 * still better what we used to do, which was like this for players
1470 * but different for monsters for no obvious reason. Currently, we
1471 * must explicitly check for special dungeons. We check for Knox
1472 * above; endgame is handled in the caller due to its different
1473 * message ("disoriented").
1475 * 3.4.2: explicitly handle quest here too, to fix the problem of
1476 * monsters sometimes level teleporting out of it into main dungeon.
1477 * Also prevent monsters reaching the Sanctum prior to invocation.
1479 if (In_quest(&u.uz)) {
1480 int bottom = dunlevs_in_dungeon(&u.uz),
1481 qlocate_depth = qlocate_level.dlevel;
1483 /* if hero hasn't reached the middle locate level yet,
1484 no one can randomly teleport past it */
1485 if (dunlev_reached(&u.uz) < qlocate_depth)
1486 bottom = qlocate_depth;
1487 min_depth = dungeons[u.uz.dnum].depth_start;
1488 max_depth = bottom + (dungeons[u.uz.dnum].depth_start - 1);
1492 dunlevs_in_dungeon(&u.uz) + (dungeons[u.uz.dnum].depth_start - 1);
1493 /* can't reach Sanctum if the invocation hasn't been performed */
1494 if (Inhell && !u.uevent.invoked)
1498 /* Get a random value relative to the current dungeon */
1499 /* Range is 1 to current+3, current not counting */
1500 nlev = rn2(cur_depth + 3 - min_depth) + min_depth;
1501 if (nlev >= cur_depth)
1504 if (nlev > max_depth) {
1506 /* teleport up if already on bottom */
1507 if (Is_botlevel(&u.uz))
1510 if (nlev < min_depth) {
1512 if (nlev == cur_depth) {
1514 if (nlev > max_depth)
1521 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1522 return false iff the attempt fails */
1524 u_teleport_mon(mtmp, give_feedback)
1526 boolean give_feedback;
1530 if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1533 pline("%s resists your magic!", Monnam(mtmp));
1535 pline("%s
\82Í
\96\82\96@
\82ð
\96h
\82¢
\82¾
\81I", Monnam(mtmp));
1537 } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1540 You("are no longer inside %s!", mon_nam(mtmp));
1542 You("%s
\82Ì
\93à
\95\94\82©
\82ç
\92E
\8fo
\82µ
\82½
\81I", mon_nam(mtmp));
1544 (void) rloc(mtmp, TRUE);
1545 } else if (is_rider(mtmp->data) && rn2(13)
1546 && enexto(&cc, u.ux, u.uy, mtmp->data))
1547 rloc_to(mtmp, cc.x, cc.y);
1549 (void) rloc(mtmp, TRUE);