1 /* NetHack 3.6 teleport.c $NHDT-Date: 1576281515 2019/12/13 23:58:35 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.95 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 STATIC_DCL boolean FDECL(tele_jump_ok, (int, int, int, int));
14 STATIC_DCL boolean FDECL(teleok, (int, int, BOOLEAN_P));
15 STATIC_DCL void NDECL(vault_tele);
16 STATIC_DCL boolean FDECL(rloc_pos_ok, (int, int, struct monst *));
17 STATIC_DCL void FDECL(mvault_tele, (struct monst *));
19 /* non-null when teleporting via having read this scroll */
20 STATIC_VAR struct obj *telescroll = 0;
23 * Is (x,y) a good position of mtmp? If mtmp is NULL, then is (x,y) good
26 * This function will only look at mtmp->mdat, so makemon, mplayer, etc can
27 * call it to generate new monster positions with fake monster structures.
30 goodpos(x, y, mtmp, gpflags)
35 struct permonst *mdat = (struct permonst *) 0;
36 boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0);
41 /* in many cases, we're trying to create a new monster, which
42 * can't go on top of the player or any existing monster.
43 * however, occasionally we are relocating engravings or objects,
44 * which could be co-located and thus get restricted a bit too much.
47 if (x == u.ux && y == u.uy
48 && mtmp != &youmonst && (mtmp != u.ustuck || !u.uswallow)
49 && (!u.usteed || mtmp != u.usteed))
53 struct monst *mtmp2 = m_at(x, y);
55 /* Be careful with long worms. A monster may be placed back in
56 * its own location. Normally, if m_at() returns the same monster
57 * that we're trying to place, the monster is being placed in its
58 * own location. However, that is not correct for worm segments,
59 * because all the segments of the worm return the same m_at().
60 * Actually we overdo the check a little bit--a worm can't be placed
61 * in its own location, period. If we just checked for mtmp->mx
62 * != x || mtmp->my != y, we'd miss the case where we're called
63 * to place the worm segment and the worm's head is at x,y.
65 if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
69 if (is_pool(x, y) && !ignorewater) {
70 /* [what about Breathless?] */
71 if (mtmp == &youmonst)
72 return (Swimming || Amphibious
73 || (!Is_waterlevel(&u.uz)
74 /* water on the Plane of Water has no surface
75 so there's no way to be on or above that */
76 && (Levitation || Flying || Wwalking)));
78 return (is_swimmer(mdat)
79 || (!Is_waterlevel(&u.uz)
80 && (is_floater(mdat) || is_flyer(mdat)
81 || is_clinger(mdat))));
82 } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
84 } else if (is_lava(x, y)) {
85 /* 3.6.3: floating eye can levitate over lava but it avoids
86 that due the effect of the heat causing it to dry out */
87 if (mdat == &mons[PM_FLOATING_EYE])
89 else if (mtmp == &youmonst)
90 return (Levitation || Flying
91 || (Fire_resistance && Wwalking && uarmf
92 && uarmf->oerodeproof)
93 || (Upolyd && likes_lava(youmonst.data)));
95 return (is_floater(mdat) || is_flyer(mdat)
98 if (passes_walls(mdat) && may_passwall(x, y))
100 if (amorphous(mdat) && closed_door(x, y))
103 if (!accessible(x, y)) {
104 if (!(is_pool(x, y) && ignorewater))
108 if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
116 * Attempt to find a good place for the given monster type in the closest
117 * position to (xx,yy). Do so in successive square rings around (xx,yy).
118 * If there is more than one valid position in the ring, choose one randomly.
119 * Return TRUE and the position chosen when successful, FALSE otherwise.
122 enexto(cc, xx, yy, mdat)
124 register xchar xx, yy;
125 struct permonst *mdat;
127 return enexto_core(cc, xx, yy, mdat, NO_MM_FLAGS);
131 enexto_core(cc, xx, yy, mdat, entflags)
134 struct permonst *mdat;
138 coord good[MAX_GOOD], *good_ptr;
140 int xmin, xmax, ymin, ymax, rangemax;
141 struct monst fakemon; /* dummy monster */
142 boolean allow_xx_yy = (boolean) ((entflags & GP_ALLOW_XY) != 0);
144 entflags &= ~GP_ALLOW_XY;
146 debugpline0("enexto() called with null mdat");
147 /* default to player's original monster type */
148 mdat = &mons[u.umonster];
151 set_mon_data(&fakemon, mdat); /* set up for goodpos */
153 /* used to use 'if (range > ROWNO && range > COLNO) return FALSE' below,
154 so effectively 'max(ROWNO, COLNO)' which performs useless iterations
155 (possibly many iterations if <xx,yy> is in the center of the map) */
156 xmax = max(xx - 1, (COLNO - 1) - xx);
157 ymax = max(yy - 0, (ROWNO - 1) - yy);
158 rangemax = max(xmax, ymax);
159 /* setup: no suitable spots yet, first iteration checks adjacent spots */
163 * Walk around the border of the square with center (xx,yy) and
164 * radius range. Stop when we find at least one valid position.
167 xmin = max(1, xx - range);
168 xmax = min(COLNO - 1, xx + range);
169 ymin = max(0, yy - range);
170 ymax = min(ROWNO - 1, yy + range);
172 for (x = xmin; x <= xmax; x++) {
173 if (goodpos(x, ymin, &fakemon, entflags)) {
176 /* beware of accessing beyond segment boundaries.. */
177 if (good_ptr++ == &good[MAX_GOOD - 1])
180 if (goodpos(x, ymax, &fakemon, entflags)) {
183 if (good_ptr++ == &good[MAX_GOOD - 1])
187 /* 3.6.3: this used to use 'ymin+1' which left top row unchecked */
188 for (y = ymin; y < ymax; y++) {
189 if (goodpos(xmin, y, &fakemon, entflags)) {
192 if (good_ptr++ == &good[MAX_GOOD - 1])
195 if (goodpos(xmax, y, &fakemon, entflags)) {
198 if (good_ptr++ == &good[MAX_GOOD - 1])
202 } while (++range <= rangemax && good_ptr == good);
204 /* return False if we exhausted 'range' without finding anything */
205 if (good_ptr == good) {
206 /* 3.6.3: earlier versions didn't have the option to try <xx,yy>,
207 and left 'cc' uninitialized when returning False */
208 cc->x = xx, cc->y = yy;
209 /* if every spot other than <xx,yy> has failed, try <xx,yy> itself */
210 if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) {
211 return TRUE; /* 'cc' is set */
213 debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy);
219 /* we've got between 1 and SIZE(good) candidates; choose one */
220 i = rn2((int) (good_ptr - good));
227 * Check for restricted areas present in some special levels. (This might
228 * need to be augmented to allow deliberate passage in wizard mode, but
229 * only for explicitly chosen destinations.)
232 tele_jump_ok(x1, y1, x2, y2)
237 if (dndest.nlx > 0) {
238 /* if inside a restricted region, can't teleport outside */
239 if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
241 && !within_bounded_area(x2, y2, dndest.nlx, dndest.nly,
242 dndest.nhx, dndest.nhy))
244 /* and if outside, can't teleport inside */
245 if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
247 && within_bounded_area(x2, y2, dndest.nlx, dndest.nly, dndest.nhx,
251 if (updest.nlx > 0) { /* ditto */
252 if (within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
254 && !within_bounded_area(x2, y2, updest.nlx, updest.nly,
255 updest.nhx, updest.nhy))
257 if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
259 && within_bounded_area(x2, y2, updest.nlx, updest.nly, updest.nhx,
272 /* allow teleportation onto vibrating square, it's not a real trap */
273 struct trap *trap = t_at(x, y);
275 if (trap && trap->ttyp != VIBRATING_SQUARE)
278 if (!goodpos(x, y, &youmonst, 0))
280 if (!tele_jump_ok(u.ux, u.uy, x, y))
282 if (!in_out_region(x, y))
288 teleds(nux, nuy, allow_drag)
289 register int nux, nuy;
292 boolean ball_active, ball_still_in_range;
293 struct monst *vault_guard = vault_occupied(u.urooms) ? findgd() : 0;
295 if (u.utraptype == TT_BURIEDBALL) {
297 buried_ball_to_punishment();
299 ball_active = (Punished && uball->where != OBJ_FREE);
300 ball_still_in_range = FALSE;
302 /* If they have to move the ball, then drag if allow_drag is true;
303 * otherwise they are teleporting, so unplacebc().
304 * If they don't have to move the ball, then always "drag" whether or
305 * not allow_drag is true, because we are calling that function, not
306 * to drag, but to move the chain. *However* there are some dumb
309 * _X move east -----> X_
311 * These are permissible if teleporting, but not if dragging. As a
312 * result, drag_ball() needs to know about allow_drag and might end
313 * up dragging the ball anyway. Also, drag_ball() might find that
314 * dragging the ball is completely impossible (ball in range but there's
315 * rock in the way), in which case it teleports the ball on its own.
318 if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) {
319 ball_still_in_range = TRUE; /* don't have to move the ball */
321 /* have to move the ball */
322 if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
323 /* we should not have dist > 1 and allow_drag at the same
324 * time, but just in case, we must then revert to teleport.
336 if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
337 /* mimics stop being unnoticed */
338 youmonst.m_ap_type = M_AP_NOTHING;
342 u.uswldtim = u.uswallow = 0;
343 if (Punished && !ball_active) {
344 /* ensure ball placement, like unstuck */
351 if (ball_still_in_range || allow_drag) {
353 xchar ballx, bally, chainx, chainy;
356 if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, &chainx,
357 &chainy, &cause_delay, allow_drag)) {
358 move_bc(0, bc_control, ballx, bally, chainx, chainy);
360 /* dragging fails if hero is encumbered beyond 'burdened' */
361 allow_drag = FALSE; /* teleport b&c to hero's new spot */
362 unplacebc(); /* to match placebc() below */
366 /* must set u.ux, u.uy after drag_ball(), which may need to know
367 the old position if allow_drag is true... */
368 u_on_newpos(nux, nuy); /* set u.<x,y>, usteed-><mx,my>; cliparound() */
369 fill_pit(u.ux0, u.uy0);
371 if (!ball_still_in_range && !allow_drag)
374 initrack(); /* teleports mess up tracking monsters without this */
375 update_player_regions();
377 * Make sure the hero disappears from the old location. This will
378 * not happen if she is teleported within sight of her previous
379 * location. Force a full vision recalculation because the hero
380 * is now in a new location.
382 newsym(u.ux0, u.uy0);
384 vision_full_recalc = 1;
386 vision_recalc(0); /* vision before effects */
387 /* if terrain type changes, levitation or flying might become blocked
388 or unblocked; might issue message, so do this after map+vision has
389 been updated for new location instead of right after u_on_newpos() */
390 if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ)
393 /* when teleporting by scroll, we need to handle discovery
394 now before getting feedback about any objects at our
395 destination since we might land on another such scroll */
396 if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0))
397 learnscroll(telescroll);
399 telescroll = 0; /* no discovery by scrolltele()'s caller */
401 /* sequencing issue: we want guard's alarm, if any, to occur before
402 room entry message, if any, so need to check for vault exit prior
403 to spoteffects; but spoteffects() sets up new value for u.urooms
404 and vault code depends upon that value, so we need to fake it */
406 char save_urooms[5]; /* [sizeof u.urooms] */
408 Strcpy(save_urooms, u.urooms);
409 Strcpy(u.urooms, in_rooms(u.ux, u.uy, VAULT));
410 /* if hero has left vault, make guard notice */
411 if (!vault_occupied(u.urooms))
412 uleftvault(vault_guard);
413 Strcpy(u.urooms, save_urooms); /* reset prior to spoteffects() */
415 /* possible shop entry message comes after guard's shrill whistle */
417 invocation_message();
421 safe_teleds(allow_drag)
424 register int nux, nuy, tcnt = 0;
427 nux = rnd(COLNO - 1);
429 } while (!teleok(nux, nuy, (boolean) (tcnt > 200)) && ++tcnt <= 400);
432 teleds(nux, nuy, allow_drag);
441 register struct mkroom *croom = search_special(VAULT);
444 if (croom && somexy(croom, &c) && teleok(c.x, c.y, FALSE)) {
445 teleds(c.x, c.y, FALSE);
452 teleport_pet(mtmp, force_it)
453 register struct monst *mtmp;
456 register struct obj *otmp;
458 if (mtmp == u.usteed)
461 if (mtmp->mleashed) {
462 otmp = get_mleash(mtmp);
464 impossible("%s is leashed, without a leash.", Monnam(mtmp));
467 if (otmp->cursed && !force_it) {
472 Your("leash goes slack.");
474 Your("
\95R
\82Í
\82½
\82é
\82ñ
\82¾
\81D");
476 m_unleash(mtmp, FALSE);
483 /* teleport the hero via some method other than scroll of teleport */
487 (void) scrolltele((struct obj *) 0);
490 /* teleport the hero; return true if scroll of teleportation should become
491 discovered; teleds() will usually do the actual discovery, since the
492 outcome sometimes depends upon destination and discovery needs to be
493 performed before arrival, in case we land on another teleport scroll */
499 boolean result = FALSE; /* don't learn scroll */
501 /* Disable teleportation in stronghold && Vlad's Tower */
502 if (level.flags.noteleport) {
505 pline("A mysterious force prevents you from teleporting!");
507 pline("
\8aï
\96
\82È
\97Í
\82ª
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I");
512 /* don't show trap if "Sorry..." */
514 make_blinded(0L, FALSE);
516 if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
518 You_feel("disoriented for a moment.");
520 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
521 if (!wizard || yn("Override?") != 'y')
524 if ((Teleport_control && !Stunned) || wizard) {
527 pline("Being unconscious, you cannot control your teleport.");
529 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");
531 #if 0 /*JP*//*
\8eå
\8cê
\82ð
\8fÈ
\97ª
\82µ
\82Ä
\8aÈ
\97ª
\89»*/
534 Strcpy(whobuf, "you");
536 Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
537 pline("Where do %s want to be teleported?", whobuf);
539 pline("
\82Ç
\82Ì
\88Ê
\92u
\82É
\8fu
\8aÔ
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
544 if (getpos(&cc, TRUE, "the desired position") < 0)
546 if (getpos(&cc, TRUE, "
\88Ú
\93®
\82µ
\82½
\82¢
\8fê
\8f\8a") < 0)
547 return TRUE; /* abort */
548 /* possible extensions: introduce a small error if
549 magic power is low; allow transfer to solid rock */
550 if (teleok(cc.x, cc.y, FALSE)) {
551 /* for scroll, discover it regardless of destination */
554 teleds(cc.x, cc.y, FALSE);
560 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
563 } else if (scroll && scroll->blessed) {
564 /* (this used to be handled in seffects()) */
566 if (yn("Do you wish to teleport?") == 'n')
568 if (yn("
\8fu
\8aÔ
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H") == 'n')
574 (void) safe_teleds(FALSE);
575 /* teleds() will leave telescroll intact iff random destination
576 is far enough away for scroll discovery to be warranted */
579 telescroll = 0; /* reset */
583 /* ^T command; 'm ^T' == choose among several teleport modes */
587 long save_HTele, save_ETele;
588 int res, added, hidden;
589 boolean ignore_restrictions = FALSE;
590 /* also defined in spell.c */
594 #define UNHIDESPELL 3
595 #define REMOVESPELL 4
597 /* normal mode; ignore 'm' prefix if it was given */
599 return dotele(FALSE);
601 added = hidden = NOOP_SPELL;
602 save_HTele = HTeleportation, save_ETele = ETeleportation;
603 if (!iflags.menu_requested) {
604 ignore_restrictions = TRUE;
606 static const struct tporttypes {
608 const char *menudesc;
611 * Potential combinations:
612 * 1) attempt ^T without intrinsic, not know spell;
613 * 2) via intrinsic, not know spell, obey restrictions;
614 * 3) via intrinsic, not know spell, ignore restrictions;
615 * 4) via intrinsic, know spell, obey restrictions;
616 * 5) via intrinsic, know spell, ignore restrictions;
617 * 6) via spell, not have intrinsic, obey restrictions;
618 * 7) via spell, not have intrinsic, ignore restrictions;
619 * 8) force, obey other restrictions;
620 * 9) force, ignore restrictions.
621 * We only support the 1st (t), 2nd (n), 6th (s), and 9th (w).
623 * This ignores the fact that there is an experience level
624 * (or poly-form) requirement which might make normal ^T fail.
626 { 'n', "normal ^T on demand; no spell, obey restrictions" },
627 { 's', "via spellcast; no intrinsic teleport" },
628 { 't', "try ^T without having it; no spell" },
629 { 'w', "debug mode; ignore restrictions" }, /* trad wizard mode */
631 menu_item *picks = (menu_item *) 0;
636 win = create_nhwindow(NHW_MENU);
639 for (i = 0; i < SIZE(tports); ++i) {
640 any.a_int = (int) tports[i].menulet;
641 add_menu(win, NO_GLYPH, &any, (char) any.a_int, 0, ATR_NONE,
643 (tports[i].menulet == 'w') ? MENU_SELECTED
646 end_menu(win, "Which way do you want to teleport?");
647 i = select_menu(win, PICK_ONE, &picks);
648 destroy_nhwindow(win);
650 tmode = picks[0].item.a_int;
651 /* if we got 2, use the one which wasn't preselected */
652 if (i > 1 && tmode == 'w')
653 tmode = picks[1].item.a_int;
654 free((genericptr_t) picks);
656 /* preselected one was explicitly chosen and got toggled off */
663 HTeleportation |= I_SPECIAL; /* confer intrinsic teleportation */
664 hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
667 HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
668 added = tport_spell(ADD_SPELL); /* add teleport-away */
671 HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
672 hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
675 ignore_restrictions = TRUE;
680 /* if dotele() can be fatal, final disclosure might lie about
681 intrinsic teleportation; we should be able to live with that
682 since the menu finagling is only applicable in wizard mode */
683 res = dotele(ignore_restrictions);
685 HTeleportation = save_HTele;
686 ETeleportation = save_ETele;
687 if (added != NOOP_SPELL || hidden != NOOP_SPELL)
688 /* can't both be non-NOOP so addition will yield the non-NOOP one */
689 (void) tport_spell(added + hidden - NOOP_SPELL);
695 dotele(break_the_rules)
696 boolean break_the_rules; /* True: wizard mode ^T */
699 const char *cantdoit;
700 boolean trap_once = FALSE;
702 trap = t_at(u.ux, u.uy);
703 if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
707 trap_once = trap->once; /* trap may get deleted, save this */
710 pline("This is a vault teleport, usable once only.");
712 pline("
\88ê
\93x
\82©
\82¬
\82è
\82Ì
\91q
\8cÉ
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82¾
\81D");
714 if (yn("Jump in?") == 'n') {
716 if (yn("
\94ò
\82Ñ
\8d\9e\82Þ
\81H") == 'n') {
725 You("%s onto the teleportation trap.",
726 locomotion(youmonst.data, "jump"));
728 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82É
\94ò
\82Ñ
\82±
\82ñ
\82¾
\81D");
732 boolean castit = FALSE;
733 register int sp_no = 0, energy = 0;
735 if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
736 && !can_teleport(youmonst.data))) {
737 /* Try to use teleport away spell.
738 Prior to 3.6.2 this used to require that you know the spellbook
739 (probably just intended as an optimization to skip the
740 lookup loop) but it is possible to know and cast a spell
741 after forgetting its book due to amnesia. */
742 for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
743 if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY)
745 /* casting isn't inhibited by being Stunned (...it ought to be) */
746 castit = (sp_no < MAXSPELL && !Confusion);
747 if (!castit && !break_the_rules) {
750 !Teleportation ? ((sp_no < MAXSPELL)
751 ? "can't cast that spell"
752 : "don't know that spell")
753 : "are not able to teleport at will");
756 !Teleportation ? ((sp_no < MAXSPELL)
757 ? "
\82»
\82Ì
\96\82\96@
\82Í
\8f¥
\82¦
\82ç
\82ê
\82È
\82¢"
758 : "
\82»
\82ñ
\82È
\96\82\96@
\82Í
\92m
\82ç
\82È
\82¢")
759 : "
\8e©
\95ª
\82Ì
\88Ó
\8ev
\82Å
\8fu
\8aÔ
\88Ú
\93®
\82Å
\82«
\82È
\82¢");
766 /* 3.6.2: the magic numbers for hunger, strength, and energy
767 have been changed to match the ones used in spelleffects().
768 Also, failing these tests used to return 1 and use a move
769 even though casting failure due to these reasons doesn't.
770 [Note: this spellev() is different from the one in spell.c
771 but they both yield the same result.] */
772 #define spellev(spell_otyp) ((int) objects[spell_otyp].oc_level)
773 energy = 5 * spellev(SPE_TELEPORT_AWAY);
774 if (break_the_rules) {
777 /* spell will cost more if carrying the Amulet, but the
778 amount is rnd(2 * energy) so we can't know by how much;
779 average is twice the normal cost, but could be triple;
780 the extra energy is spent even if that results in not
781 having enough to cast (which also uses the move) */
782 else if (u.uen < energy)
784 } else if (u.uhunger <= 10) {
786 cantdoit = "are too weak from hunger";
788 cantdoit = "
\82É
\82Í
\82¨
\82È
\82©
\82ª
\8bó
\82«
\82·
\82¬
\82Ä
\82¢
\82é";
789 } else if (ACURR(A_STR) < 4) {
791 cantdoit = "lack the strength";
793 cantdoit = "
\82¾
\82¯
\82Ì
\97Í
\82ª
\82È
\82¢";
794 } else if (energy > u.uen) {
796 cantdoit = "lack the energy";
798 cantdoit = "
\82¾
\82¯
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\82È
\82¢";
802 You("%s %s.", cantdoit,
803 castit ? "for a teleport spell" : "to teleport");
805 You("%s%s
\81D", cantdoit,
806 castit ? "
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é" : "
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é");
809 } else if (check_capacity(
811 "Your concentration falters from carrying so much.")) {
813 "
\91ò
\8eR
\82à
\82Ì
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\8fW
\92\86\82Å
\82«
\82È
\82¢
\81D")) {
814 return 1; /* this failure in spelleffects() also uses the move */
818 /* energy cost is deducted in spelleffects() */
819 exercise(A_WIS, TRUE);
820 if (spelleffects(sp_no, TRUE))
822 else if (!break_the_rules)
825 /* bypassing spelleffects(); apply energy cost directly */
832 if (trap && trap_once)
838 You("%s", shudder_for_moment);
851 const char *escape_by_flying = 0; /* when surviving dest of -N */
853 boolean force_dest = FALSE;
855 if (iflags.debug_fuzzer)
856 goto random_levtport;
857 if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
860 You_feel("very disoriented for a moment.");
862 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
865 if ((Teleport_control && !Stunned) || wizard) {
870 Strcpy(qbuf, "To what level do you want to teleport?");
872 Strcpy(qbuf, "
\89½
\8aK
\82É
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
874 if (iflags.menu_requested) {
875 /* wizard mode 'm ^V' skips prompting on first pass
876 (note: level Tport via menu won't have any second pass) */
877 iflags.menu_requested = FALSE;
884 Strcat(qbuf, " [type a number, name, or ? for a menu]");
886 Strcat(qbuf, " [
\90\94\8e\9a\82©
\96¼
\91O
\82ð
\82¢
\82ê
\82Ä
\82Ë
\81D?
\82Å
\83\81\83j
\83\85\81[]");
889 Strcat(qbuf, " [type a number or name]");
891 Strcat(qbuf, " [
\90\94\8e\9a\82©
\96¼
\91O
\82ð
\82¢
\82ê
\82Ä
\82Ë]");
893 *buf = '\0'; /* EDIT_GETLIN: if we're on second or later pass,
894 the previous input was invalid so don't use it
895 as getlin()'s preloaded default answer */
897 if (!strcmp(buf, "\033")) { /* cancelled */
898 if (Confusion && rnl(5)) {
902 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
903 goto random_levtport;
906 } else if (!strcmp(buf, "*")) {
907 goto random_levtport;
908 } else if (Confusion && rnl(5)) {
912 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
913 goto random_levtport;
915 if (wizard && !strcmp(buf, "?")) {
922 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
926 newlevel.dnum = destdnum;
927 newlevel.dlevel = destlev;
928 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
932 && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
934 /* ordinarily we'd use hold_another_object()
935 for something like this, but we don't want
936 fumbling or already full pack to interfere */
938 prinv("Endgame prerequisite:", amu, 0L);
942 } else if ((newlev = lev_by_name(buf)) == 0)
944 } while (!newlev && !digit(buf[0])
945 && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
947 /* no dungeon escape via this route */
950 goto random_levtport;
952 if (ynq("Go to Nowhere. Are you sure?") != 'y')
954 if (ynq("
\82Ç
\82±
\82Æ
\82à
\92m
\82ê
\82Ê
\8fê
\8f\8a\82É
\8ds
\82«
\82Ü
\82·
\81D
\82æ
\82ë
\82µ
\82¢
\82Å
\82·
\82©
\81H") != 'y')
957 You("%s in agony as your body begins to warp...",
958 is_silent(youmonst.data) ? "writhe" : "scream");
960 You("
\91Ì
\82ª
\88Ú
\93®
\82µ
\82Í
\82¶
\82ß
\82é
\82Æ
\81C
\8bê
\82µ
\82Ý%s
\81D
\81D
\81D",
961 is_silent(youmonst.data) ? "
\82Å
\90g
\82à
\82¾
\82¦
\82µ
\82½" : "
\82Ì
\82 \82¦
\82¬
\90º
\82ð
\8fo
\82µ
\82½");
963 display_nhwindow(WIN_MESSAGE, FALSE);
965 You("cease to exist.");
967 Your("
\91¶
\8dÝ
\82Í
\8fÁ
\96Å
\82µ
\82½
\81D");
970 Your("possessions land on the %s with a thud.",
972 Your("
\8e\9d\82¿
\82à
\82Ì
\82Í
\83h
\83T
\83b
\82Æ%s
\82É
\97\8e\82¿
\82½
\81D",
973 surface(u.ux, u.uy));
974 killer.format = NO_KILLER_PREFIX;
976 Strcpy(killer.name, "committed suicide");
978 Strcpy(killer.name, "
\8e©
\8eE
\82µ
\82½");
981 pline("An energized cloud of dust begins to coalesce.");
983 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");
985 Your("body rematerializes%s.",
986 invent ? ", and you gather up all your possessions" : "");
988 Your("
\91Ì
\82Í
\8dÄ
\82Ñ
\8eÀ
\91Ì
\89»
\82µ
\82½
\81D%s",
989 invent ? "
\82»
\82µ
\82Ä
\91S
\82Ä
\82Ì
\8e\9d\82¿
\95¨
\82ð
\8fE
\82¢
\8fã
\82°
\82½
\81D" : "");
994 /* if in Knox and the requested level > 0, stay put.
995 * we let negative values requests fall into the "heaven" loop.
997 if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
998 You1(shudder_for_moment);
1001 /* if in Quest, the player sees "Home 1", etc., on the status
1002 * line, instead of the logical depth of the level. controlled
1003 * level teleport request is likely to be relativized to the
1004 * status line, and consequently it should be incremented to
1005 * the value of the logical depth of the target level.
1007 * we let negative values requests fall into the "heaven" loop.
1009 if (In_quest(&u.uz) && newlev > 0)
1010 newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
1011 } else { /* involuntary level tele */
1013 newlev = random_teleport_level();
1014 if (newlev == depth(&u.uz)) {
1015 You1(shudder_for_moment);
1020 if (u.utrap && u.utraptype == TT_BURIEDBALL)
1021 buried_ball_to_punishment();
1023 if (!next_to_u() && !force_dest) {
1024 You1(shudder_for_moment);
1027 if (In_endgame(&u.uz)) { /* must already be wizard */
1028 int llimit = dunlevs_in_dungeon(&u.uz);
1030 if (newlev >= 0 || newlev <= -llimit) {
1032 You_cant("get there from here.");
1034 You("
\82»
\82±
\82É
\82Í
\8ds
\82¯
\82È
\82¢
\81D");
1037 newlevel.dnum = u.uz.dnum;
1038 newlevel.dlevel = llimit + newlev;
1039 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1043 killer.name[0] = 0; /* still alive, so far... */
1045 if (iflags.debug_fuzzer && newlev < 0)
1046 goto random_levtport;
1047 if (newlev < 0 && !force_dest) {
1049 /* take unpaid inventory items off of shop bills */
1050 in_mklev = TRUE; /* suppress map update */
1051 u_left_shop(u.ushops0, TRUE);
1052 /* you're now effectively out of the shop */
1053 *u.ushops0 = *u.ushops = '\0';
1056 if (newlev <= -10) {
1058 You("arrive in heaven.");
1060 You("
\93V
\8d\91\82É
\92H
\82è
\82Â
\82¢
\82½
\81D");
1062 verbalize("Thou art early, but we'll admit thee.");
1064 verbalize("
\93ð
\81C
\8e\80\82Ê
\82É
\82Í
\91\81\82·
\82¬
\82é
\82ª
\82»
\82ê
\82à
\82æ
\82©
\82ë
\82¤
\81D");
1065 killer.format = NO_KILLER_PREFIX;
1067 Strcpy(killer.name, "went to heaven prematurely");
1069 Strcpy(killer.name, "
\8eá
\82
\82µ
\82Ä
\93V
\8d\91\82É
\8ds
\82Á
\82½");
1070 } else if (newlev == -9) {
1072 You_feel("deliriously happy.");
1074 You("
\8b¶
\82Á
\82½
\82æ
\82¤
\82È
\8dK
\82¹
\82ð
\8a´
\82¶
\82½
\81D");
1076 pline("(In fact, you're on Cloud 9!)");
1078 pline("(
\96{
\93\96\82É
\8bê
\82ð
\8fæ
\82è
\89z
\82¦
\82½
\8fê
\8f\8a\82É
\82¢
\82é
\81I) ");
1079 display_nhwindow(WIN_MESSAGE, FALSE);
1082 You("are now high above the clouds...");
1084 You("
\89_
\82Ì
\97y
\82©
\8fã
\82É
\82¢
\82é
\81D
\81D
\81D");
1086 if (killer.name[0]) {
1087 ; /* arrival in heaven is pending */
1088 } else if (Levitation) {
1090 escape_by_flying = "float gently down to earth";
1092 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
1093 } else if (Flying) {
1095 escape_by_flying = "fly down to the ground";
1097 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
1100 pline("Unfortunately, you don't know how to fly.");
1102 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í
\94ò
\82Ñ
\82©
\82½
\82ð
\92m
\82ç
\82È
\82¢
\81D");
1104 You("plummet a few thousand feet to your death.");
1106 pline("
\90\94\90ç
\83t
\83B
\81[
\83g
\82Ì
\8e\80\82Ì
\83_
\83C
\83r
\83\93\83O
\82¾
\81I");
1108 Sprintf(killer.name,
1109 "teleported out of the dungeon and fell to %s death",
1111 killer.format = NO_KILLER_PREFIX;
1113 Strcpy(killer.name, "
\96À
\8b{
\82ð
\94ò
\82Ñ
\82¾
\82µ
\83_
\83C
\83r
\83\93\83O
\82µ
\82Ä");
1114 killer.format = KILLED_BY;
1119 if (killer.name[0]) { /* the chosen destination was not survivable */
1122 /* set specific death location; this also suppresses bones */
1123 lsav = u.uz; /* save current level, see below */
1124 u.uz.dnum = 0; /* main dungeon */
1125 u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */
1127 /* can only get here via life-saving (or declining to die in
1128 explore|debug mode); the hero has now left the dungeon... */
1130 escape_by_flying = "find yourself back on the surface";
1132 escape_by_flying = "
\8bC
\82ª
\82Â
\82¢
\82½
\82ç
\92n
\8fã
\82É
\96ß
\82Á
\82Ä
\82¢
\82½";
1133 u.uz = lsav; /* restore u.uz so escape code works */
1136 /* calls done(ESCAPED) if newlevel==0 */
1137 if (escape_by_flying) {
1139 You("%s.", escape_by_flying);
1141 You("%s
\81D", escape_by_flying);
1142 newlevel.dnum = 0; /* specify main dungeon */
1143 newlevel.dlevel = 0; /* escape the dungeon */
1144 /* [dlevel used to be set to 1, but it doesn't make sense to
1145 teleport out of the dungeon and float or fly down to the
1146 surface but then actually arrive back inside the dungeon] */
1147 } else if (u.uz.dnum == medusa_level.dnum
1148 && newlev >= dungeons[u.uz.dnum].depth_start
1149 + dunlevs_in_dungeon(&u.uz)) {
1150 if (!(wizard && force_dest))
1151 find_hell(&newlevel);
1153 /* if invocation did not yet occur, teleporting into
1154 * the last level of Gehennom is forbidden.
1156 if (!wizard && Inhell && !u.uevent.invoked
1157 && newlev >= (dungeons[u.uz.dnum].depth_start
1158 + dunlevs_in_dungeon(&u.uz) - 1)) {
1159 newlev = dungeons[u.uz.dnum].depth_start
1160 + dunlevs_in_dungeon(&u.uz) - 2;
1164 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
1166 /* no teleporting out of quest dungeon */
1167 if (In_quest(&u.uz) && newlev < depth(&qstart_level))
1168 newlev = depth(&qstart_level);
1169 /* the player thinks of levels purely in logical terms, so
1170 * we must translate newlev to a number relative to the
1173 if (!(wizard && force_dest))
1174 get_level(&newlevel, newlev);
1176 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1177 /* in case player just read a scroll and is about to be asked to
1178 call it something, we can't defer until the end of the turn */
1179 if (u.utotype && !context.mon_moving)
1185 register struct trap *ttmp;
1187 struct d_level target_level;
1189 if (u.utrap && u.utraptype == TT_BURIEDBALL)
1190 buried_ball_to_punishment();
1193 You1(shudder_for_moment);
1197 /* if landed from another portal, do nothing */
1198 /* problem: level teleport landing escapes the check */
1199 if (!on_level(&u.uz, &u.uz0))
1203 You("activated a magic portal!");
1205 pline("
\96\82\96@
\82Ì
\93ü
\8cû
\82ª
\8dì
\93®
\82µ
\82½
\81I");
1207 /* prevent the poor shnook, whose amulet was stolen while in
1208 * the endgame, from accidently triggering the portal to the
1209 * next level, and thus losing the game
1211 if (In_endgame(&u.uz) && !u.uhave.amulet) {
1213 You_feel("dizzy for a moment, but nothing happens...");
1215 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");
1219 target_level = ttmp->dst;
1220 schedule_goto(&target_level, FALSE, FALSE, 1,
1222 "You feel dizzy for a moment, but the sensation passes.",
1224 "
\88ê
\8fu
\82ß
\82Ü
\82¢
\82ð
\8a´
\82¶
\82½
\81C
\82µ
\82©
\82µ
\82»
\82Ì
\8a´
\8ao
\82Í
\8fÁ
\82¦
\82½
\81D",
1232 if (In_endgame(&u.uz) || Antimagic) {
1234 shieldeff(u.ux, u.uy);
1236 You_feel("a wrenching sensation.");
1238 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1239 } else if (!next_to_u()) {
1240 You1(shudder_for_moment);
1241 } else if (trap->once) {
1243 newsym(u.ux, u.uy); /* get rid of trap symbol */
1250 level_tele_trap(trap, trflags)
1255 char verbbuf[BUFSZ];
1257 if ((trflags & VIASITTING) != 0)
1258 Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1260 Sprintf(verbbuf, "%s onto",
1261 Levitation ? (const char *) "float"
1262 : locomotion(youmonst.data, "step"));
1263 You("%s a level teleport trap!", verbbuf);
1265 if ((trflags & VIASITTING) != 0) {
1266 pline("
\95Ê
\82Ì
\8aK
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82ª
\94
\93®
\82µ
\82½
\81I");
1268 You("
\95Ê
\82Ì
\8aK
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82ð%s
\81I",
1269 Levitation ? (const char *) "
\8c©
\89º
\82ë
\82µ
\82½"
1270 : jpast(locomotion(youmonst.data, "
\93¥
\82Þ")));
1275 shieldeff(u.ux, u.uy);
1277 if (Antimagic || In_endgame(&u.uz)) {
1279 You_feel("a wrenching sensation.");
1281 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1286 You("are momentarily blinded by a flash of light.");
1288 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81D");
1291 You("are momentarily disoriented.");
1293 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D");
1295 newsym(u.ux, u.uy); /* get rid of trap symbol */
1299 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1301 rloc_pos_ok(x, y, mtmp)
1302 register int x, y; /* coordinates of candidate location */
1305 register int xx, yy;
1307 if (!goodpos(x, y, mtmp, 0))
1310 * Check for restricted areas present in some special levels.
1312 * `xx' is current column; if 0, then `yy' will contain flag bits
1313 * rather than row: bit #0 set => moving upwards; bit #1 set =>
1314 * inside the Wizard's tower.
1319 /* no current location (migrating monster arrival) */
1320 if (dndest.nlx && On_W_tower_level(&u.uz))
1321 return (((yy & 2) != 0)
1322 /* inside xor not within */
1323 ^ !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1324 dndest.nhx, dndest.nhy));
1325 if (updest.lx && (yy & 1) != 0) /* moving up */
1326 return (within_bounded_area(x, y, updest.lx, updest.ly,
1327 updest.hx, updest.hy)
1329 || !within_bounded_area(x, y, updest.nlx, updest.nly,
1330 updest.nhx, updest.nhy)));
1331 if (dndest.lx && (yy & 1) == 0) /* moving down */
1332 return (within_bounded_area(x, y, dndest.lx, dndest.ly,
1333 dndest.hx, dndest.hy)
1335 || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1336 dndest.nhx, dndest.nhy)));
1338 /* [try to] prevent a shopkeeper or temple priest from being
1339 sent out of his room (caller might resort to goodpos() if
1340 we report failure here, so this isn't full prevention) */
1341 if (mtmp->isshk && inhishop(mtmp)) {
1342 if (levl[x][y].roomno != ESHK(mtmp)->shoproom)
1344 } else if (mtmp->ispriest && inhistemple(mtmp)) {
1345 if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1348 /* current location is <xx,yy> */
1349 if (!tele_jump_ok(xx, yy, x, y))
1359 * Pulls a monster from its current position and places a monster at
1360 * a new x and y. If oldx is 0, then the monster was not in the
1361 * levels.monsters array. However, if oldx is 0, oldy may still have
1362 * a value because mtmp is a migrating_mon. Worm tails are always
1363 * placed randomly around the head of the worm.
1370 register int oldx = mtmp->mx, oldy = mtmp->my;
1371 boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1373 if (x == mtmp->mx && y == mtmp->my && m_at(x, y) == mtmp)
1374 return; /* that was easy */
1376 if (oldx) { /* "pick up" monster */
1380 remove_monster(oldx, oldy);
1381 newsym(oldx, oldy); /* update old location */
1385 memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
1386 place_monster(mtmp, x, y); /* put monster down */
1387 update_monster_region(mtmp);
1389 if (mtmp->wormno) /* now put down tail */
1390 place_worm_tail_randomly(mtmp, x, y);
1392 if (u.ustuck == mtmp) {
1394 u_on_newpos(mtmp->mx, mtmp->my);
1396 } else if (distu(mtmp->mx, mtmp->my) > 2) {
1401 newsym(x, y); /* update new location */
1402 set_apparxy(mtmp); /* orient monster */
1404 /* shopkeepers will only teleport if you zap them with a wand of
1405 teleportation or if they've been transformed into a jumpy monster;
1406 the latter only happens if you've attacked them with polymorph */
1407 if (resident_shk && !inhishop(mtmp))
1408 make_angry_shk(mtmp, oldx, oldy);
1411 /* place a monster at a random location, typically due to teleport */
1412 /* return TRUE if successful, FALSE if not */
1414 rloc(mtmp, suppress_impossible)
1415 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1416 boolean suppress_impossible;
1418 register int x, y, trycount;
1420 if (mtmp == u.usteed) {
1425 if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */
1426 if (!In_W_tower(u.ux, u.uy, &u.uz))
1427 x = xupstair, y = yupstair;
1428 else if (!xdnladder) /* bottom level of tower */
1429 x = xupladder, y = yupladder;
1431 x = xdnladder, y = ydnladder;
1432 /* if the wiz teleports away to heal, try the up staircase,
1433 to block the player's escaping before he's healed
1434 (deliberately use `goodpos' rather than `rloc_pos_ok' here) */
1435 if (goodpos(x, y, mtmp, 0))
1441 x = rn1(COLNO - 3, 2);
1443 if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1444 : goodpos(x, y, mtmp, 0))
1446 } while (++trycount < 1000);
1448 /* last ditch attempt to find a good place */
1449 for (x = 2; x < COLNO - 1; x++)
1450 for (y = 0; y < ROWNO; y++)
1451 if (goodpos(x, y, mtmp, 0))
1454 /* level either full of monsters or somehow faulty */
1455 if (!suppress_impossible)
1456 impossible("rloc(): couldn't relocate monster");
1460 rloc_to(mtmp, x, y);
1468 struct mkroom *croom = search_special(VAULT);
1471 if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1472 rloc_to(mtmp, c.x, c.y);
1475 (void) rloc(mtmp, TRUE);
1482 if (level.flags.noteleport) {
1485 pline("A mysterious force prevents %s from teleporting!",
1488 pline("
\8aï
\96
\82È
\97Í
\82ª%s
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I",
1497 mtele_trap(mtmp, trap, in_sight)
1504 if (tele_restrict(mtmp))
1506 if (teleport_pet(mtmp, FALSE)) {
1507 /* save name with pre-movement visibility */
1508 monname = Monnam(mtmp);
1510 /* Note: don't remove the trap if a vault. Other-
1511 * wise the monster will be stuck there, since
1512 * the guard isn't going to come for it...
1517 (void) rloc(mtmp, TRUE);
1520 if (canseemon(mtmp))
1522 pline("%s seems disoriented.", monname);
1524 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D", monname);
1527 pline("%s suddenly disappears!", monname);
1529 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", monname);
1535 /* return 0 if still on level, 3 if not */
1537 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1543 int tt = (trap ? trap->ttyp : NO_TRAP);
1545 if (mtmp == u.ustuck) /* probably a vortex */
1546 return 0; /* temporary? kludge */
1547 if (teleport_pet(mtmp, force_it)) {
1549 int migrate_typ = MIGR_RANDOM;
1552 if (Is_stronghold(&u.uz)) {
1553 assign_level(&tolevel, &valley_level);
1554 } else if (Is_botlevel(&u.uz)) {
1555 if (in_sight && trap->tseen)
1557 pline("%s avoids the %s.", Monnam(mtmp),
1558 (tt == HOLE) ? "hole" : "trap");
1560 pline("%s
\82Í%s
\82ð
\89ñ
\94ð
\82µ
\82½
\81D", Monnam(mtmp),
1561 (tt == HOLE) ? "
\8c\8a" : "ã©");
1565 get_level(&tolevel, depth(&u.uz) + 1);
1567 } else if (tt == MAGIC_PORTAL) {
1568 if (In_endgame(&u.uz) && (mon_has_amulet(mtmp)
1569 || is_home_elemental(mtmp->data)
1571 if (in_sight && mtmp->data->mlet != S_ELEMENTAL) {
1573 pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1575 pline("%s
\82ª
\88ê
\8fu
\8bP
\82¢
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81D", Monnam(mtmp));
1580 assign_level(&tolevel, &trap->dst);
1581 migrate_typ = MIGR_PORTAL;
1583 } else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
1586 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)
1587 /* NO_TRAP is used when forcing a monster off the level;
1588 onscary(0,0,) is true for the Wizard, Riders, lawful
1589 minions, Angels of any alignment, shopkeeper or priest
1590 currently inside his or her own special room */
1591 || (tt == NO_TRAP && onscary(0, 0, mtmp))) {
1594 pline("%s seems very disoriented for a moment.",
1596 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
1600 if (tt == NO_TRAP) {
1601 /* creature is being forced off the level to make room;
1602 it will try to return to this level (at a random spot
1603 rather than its current one) if the level is left by
1604 the hero and then revisited */
1605 assign_level(&tolevel, &u.uz);
1607 nlev = random_teleport_level();
1608 if (nlev == depth(&u.uz)) {
1611 pline("%s shudders for a moment.", Monnam(mtmp));
1613 pline("%s
\82Í
\88ê
\8fu
\90k
\82¦
\82½
\81D", Monnam(mtmp));
1616 get_level(&tolevel, nlev);
1619 impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
1625 pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1627 pline("
\93Ë
\91R%s
\82ª
\8e\8b\8aE
\82©
\82ç
\8fÁ
\82¦
\82½
\81D", mon_nam(mtmp));
1631 migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1632 return 3; /* no longer on this level */
1637 /* place object randomly, returns False if it's gone (eg broken) */
1640 register struct obj *obj;
1642 register xchar tx, ty, otx, oty;
1643 boolean restricted_fall;
1644 int try_limit = 4000;
1646 if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1647 if (revive_corpse(obj))
1651 obj_extract_self(obj);
1654 restricted_fall = (otx == 0 && dndest.lx);
1656 tx = rn1(COLNO - 3, 2);
1660 } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1662 && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1663 dndest.hx, dndest.hy)
1665 && within_bounded_area(tx, ty,
1666 dndest.nlx, dndest.nly,
1667 dndest.nhx, dndest.nhy))))
1668 /* on the Wizard Tower levels, objects inside should
1669 stay inside and objects outside should stay outside */
1670 || (dndest.nlx && On_W_tower_level(&u.uz)
1671 && within_bounded_area(tx, ty, dndest.nlx, dndest.nly,
1672 dndest.nhx, dndest.nhy)
1673 != within_bounded_area(otx, oty, dndest.nlx, dndest.nly,
1674 dndest.nhx, dndest.nhy)));
1677 if (flooreffects(obj, tx, ty, "fall")) {
1679 if (flooreffects(obj, tx, ty, "
\97\8e\82¿
\82é")) {
1680 /* update old location since flooreffects() couldn't;
1681 unblock_point() for boulder handled by obj_extract_self() */
1684 } else if (otx == 0 && oty == 0) {
1685 ; /* fell through a trap door; no update of old loc needed */
1687 if (costly_spot(otx, oty)
1688 && (!costly_spot(tx, ty)
1689 || !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) {
1690 if (costly_spot(u.ux, u.uy)
1691 && index(u.urooms, *in_rooms(otx, oty, 0)))
1692 addtobill(obj, FALSE, FALSE, FALSE);
1694 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1696 newsym(otx, oty); /* update old location */
1698 place_object(obj, tx, ty);
1699 /* note: block_point() for boulder handled by place_object() */
1704 /* Returns an absolute depth */
1706 random_teleport_level()
1708 int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1710 /* [the endgame case can only occur in wizard mode] */
1711 if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1714 /* What I really want to do is as follows:
1715 * -- If in a dungeon that goes down, the new level is to be restricted
1716 * to [top of parent, bottom of current dungeon]
1717 * -- If in a dungeon that goes up, the new level is to be restricted
1718 * to [top of current dungeon, bottom of parent]
1719 * -- If in a quest dungeon or similar dungeon entered by portals,
1720 * the new level is to be restricted to [top of current dungeon,
1721 * bottom of current dungeon]
1722 * The current behavior is not as sophisticated as that ideal, but is
1723 * still better what we used to do, which was like this for players
1724 * but different for monsters for no obvious reason. Currently, we
1725 * must explicitly check for special dungeons. We check for Knox
1726 * above; endgame is handled in the caller due to its different
1727 * message ("disoriented").
1729 * 3.4.2: explicitly handle quest here too, to fix the problem of
1730 * monsters sometimes level teleporting out of it into main dungeon.
1731 * Also prevent monsters reaching the Sanctum prior to invocation.
1733 if (In_quest(&u.uz)) {
1734 int bottom = dunlevs_in_dungeon(&u.uz),
1735 qlocate_depth = qlocate_level.dlevel;
1737 /* if hero hasn't reached the middle locate level yet,
1738 no one can randomly teleport past it */
1739 if (dunlev_reached(&u.uz) < qlocate_depth)
1740 bottom = qlocate_depth;
1741 min_depth = dungeons[u.uz.dnum].depth_start;
1742 max_depth = bottom + (dungeons[u.uz.dnum].depth_start - 1);
1746 dunlevs_in_dungeon(&u.uz) + (dungeons[u.uz.dnum].depth_start - 1);
1747 /* can't reach Sanctum if the invocation hasn't been performed */
1748 if (Inhell && !u.uevent.invoked)
1752 /* Get a random value relative to the current dungeon */
1753 /* Range is 1 to current+3, current not counting */
1754 nlev = rn2(cur_depth + 3 - min_depth) + min_depth;
1755 if (nlev >= cur_depth)
1758 if (nlev > max_depth) {
1760 /* teleport up if already on bottom */
1761 if (Is_botlevel(&u.uz))
1764 if (nlev < min_depth) {
1766 if (nlev == cur_depth) {
1768 if (nlev > max_depth)
1775 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1776 return false iff the attempt fails */
1778 u_teleport_mon(mtmp, give_feedback)
1780 boolean give_feedback;
1784 if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1787 pline("%s resists your magic!", Monnam(mtmp));
1789 pline("%s
\82Í
\96\82\96@
\82ð
\96h
\82¢
\82¾
\81I", Monnam(mtmp));
1791 } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1794 You("are no longer inside %s!", mon_nam(mtmp));
1796 You("%s
\82Ì
\93à
\95\94\82©
\82ç
\92E
\8fo
\82µ
\82½
\81I", mon_nam(mtmp));
1798 (void) rloc(mtmp, TRUE);
1799 } else if (is_rider(mtmp->data) && rn2(13)
1800 && enexto(&cc, u.ux, u.uy, mtmp->data))
1801 rloc_to(mtmp, cc.x, cc.y);
1803 (void) rloc(mtmp, TRUE);