1 /* NetHack 3.6 teleport.c $NHDT-Date: 1553885439 2019/03/29 18:50:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.86 $ */
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-2019 */
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 (mtmp != &youmonst && x == u.ux && y == u.uy
48 && (!u.usteed || mtmp != u.usteed))
52 struct monst *mtmp2 = m_at(x, y);
54 /* Be careful with long worms. A monster may be placed back in
55 * its own location. Normally, if m_at() returns the same monster
56 * that we're trying to place, the monster is being placed in its
57 * own location. However, that is not correct for worm segments,
58 * because all the segments of the worm return the same m_at().
59 * Actually we overdo the check a little bit--a worm can't be placed
60 * in its own location, period. If we just checked for mtmp->mx
61 * != x || mtmp->my != y, we'd miss the case where we're called
62 * to place the worm segment and the worm's head is at x,y.
64 if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
68 if (is_pool(x, y) && !ignorewater) {
69 if (mtmp == &youmonst)
70 return (Levitation || Flying || Wwalking || Swimming
73 return (is_floater(mdat) || is_flyer(mdat) || is_swimmer(mdat)
75 } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
77 } else if (is_lava(x, y)) {
78 if (mtmp == &youmonst)
79 return (Levitation || Flying
80 || (Fire_resistance && Wwalking && uarmf
81 && uarmf->oerodeproof)
82 || (Upolyd && likes_lava(youmonst.data)));
84 return (is_floater(mdat) || is_flyer(mdat)
87 if (passes_walls(mdat) && may_passwall(x, y))
89 if (amorphous(mdat) && closed_door(x, y))
92 if (!accessible(x, y)) {
93 if (!(is_pool(x, y) && ignorewater))
97 if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
105 * Attempt to find a good place for the given monster type in the closest
106 * position to (xx,yy). Do so in successive square rings around (xx,yy).
107 * If there is more than one valid position in the ring, choose one randomly.
108 * Return TRUE and the position chosen when successful, FALSE otherwise.
111 enexto(cc, xx, yy, mdat)
113 register xchar xx, yy;
114 struct permonst *mdat;
116 return enexto_core(cc, xx, yy, mdat, 0);
120 enexto_core(cc, xx, yy, mdat, entflags)
122 register xchar xx, yy;
123 struct permonst *mdat;
127 coord good[MAX_GOOD], *good_ptr;
129 int xmin, xmax, ymin, ymax;
130 struct monst fakemon; /* dummy monster */
133 debugpline0("enexto() called with null mdat");
134 /* default to player's original monster type */
135 mdat = &mons[u.umonster];
138 set_mon_data(&fakemon, mdat); /* set up for goodpos */
143 * Walk around the border of the square with center (xx,yy) and
144 * radius range. Stop when we find at least one valid position.
147 xmin = max(1, xx - range);
148 xmax = min(COLNO - 1, xx + range);
149 ymin = max(0, yy - range);
150 ymax = min(ROWNO - 1, yy + range);
152 for (x = xmin; x <= xmax; x++)
153 if (goodpos(x, ymin, &fakemon, entflags)) {
156 /* beware of accessing beyond segment boundaries.. */
157 if (good_ptr++ == &good[MAX_GOOD - 1])
160 for (x = xmin; x <= xmax; x++)
161 if (goodpos(x, ymax, &fakemon, entflags)) {
164 /* beware of accessing beyond segment boundaries.. */
165 if (good_ptr++ == &good[MAX_GOOD - 1])
168 for (y = ymin + 1; y < ymax; y++)
169 if (goodpos(xmin, y, &fakemon, entflags)) {
172 /* beware of accessing beyond segment boundaries.. */
173 if (good_ptr++ == &good[MAX_GOOD - 1])
176 for (y = ymin + 1; y < ymax; y++)
177 if (goodpos(xmax, y, &fakemon, entflags)) {
180 /* beware of accessing beyond segment boundaries.. */
181 if (good_ptr++ == &good[MAX_GOOD - 1])
186 /* return if we've grown too big (nothing is valid) */
187 if (range > ROWNO && range > COLNO)
189 } while (good_ptr == good);
192 i = rn2((int) (good_ptr - good));
199 * Check for restricted areas present in some special levels. (This might
200 * need to be augmented to allow deliberate passage in wizard mode, but
201 * only for explicitly chosen destinations.)
204 tele_jump_ok(x1, y1, x2, y2)
209 if (dndest.nlx > 0) {
210 /* if inside a restricted region, can't teleport outside */
211 if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
213 && !within_bounded_area(x2, y2, dndest.nlx, dndest.nly,
214 dndest.nhx, dndest.nhy))
216 /* and if outside, can't teleport inside */
217 if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
219 && within_bounded_area(x2, y2, dndest.nlx, dndest.nly, dndest.nhx,
223 if (updest.nlx > 0) { /* ditto */
224 if (within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
226 && !within_bounded_area(x2, y2, updest.nlx, updest.nly,
227 updest.nhx, updest.nhy))
229 if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
231 && within_bounded_area(x2, y2, updest.nlx, updest.nly, updest.nhx,
243 if (!trapok && t_at(x, y))
245 if (!goodpos(x, y, &youmonst, 0))
247 if (!tele_jump_ok(u.ux, u.uy, x, y))
249 if (!in_out_region(x, y))
255 teleds(nux, nuy, allow_drag)
256 register int nux, nuy;
259 boolean ball_active, ball_still_in_range;
260 struct monst *vault_guard = vault_occupied(u.urooms) ? findgd() : 0;
262 if (u.utraptype == TT_BURIEDBALL) {
264 buried_ball_to_punishment();
266 ball_active = (Punished && uball->where != OBJ_FREE);
267 ball_still_in_range = FALSE;
269 /* If they have to move the ball, then drag if allow_drag is true;
270 * otherwise they are teleporting, so unplacebc().
271 * If they don't have to move the ball, then always "drag" whether or
272 * not allow_drag is true, because we are calling that function, not
273 * to drag, but to move the chain. *However* there are some dumb
276 * _X move east -----> X_
278 * These are permissible if teleporting, but not if dragging. As a
279 * result, drag_ball() needs to know about allow_drag and might end
280 * up dragging the ball anyway. Also, drag_ball() might find that
281 * dragging the ball is completely impossible (ball in range but there's
282 * rock in the way), in which case it teleports the ball on its own.
285 if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2)
286 ball_still_in_range = TRUE; /* don't have to move the ball */
288 /* have to move the ball */
289 if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
290 /* we should not have dist > 1 and allow_drag at the same
291 * time, but just in case, we must then revert to teleport.
303 if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
304 /* mimics stop being unnoticed */
305 youmonst.m_ap_type = M_AP_NOTHING;
309 u.uswldtim = u.uswallow = 0;
310 if (Punished && !ball_active) {
311 /* ensure ball placement, like unstuck */
318 if (ball_still_in_range || allow_drag) {
320 xchar ballx, bally, chainx, chainy;
323 if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, &chainx,
324 &chainy, &cause_delay, allow_drag))
325 move_bc(0, bc_control, ballx, bally, chainx, chainy);
328 /* must set u.ux, u.uy after drag_ball(), which may need to know
329 the old position if allow_drag is true... */
330 u_on_newpos(nux, nuy); /* set u.<x,y>, usteed-><mx,my>; cliparound() */
331 fill_pit(u.ux0, u.uy0);
333 if (!ball_still_in_range && !allow_drag)
336 initrack(); /* teleports mess up tracking monsters without this */
337 update_player_regions();
339 * Make sure the hero disappears from the old location. This will
340 * not happen if she is teleported within sight of her previous
341 * location. Force a full vision recalculation because the hero
342 * is now in a new location.
344 newsym(u.ux0, u.uy0);
346 vision_full_recalc = 1;
348 vision_recalc(0); /* vision before effects */
349 /* if terrain type changes, levitation or flying might become blocked
350 or unblocked; might issue message, so do this after map+vision has
351 been updated for new location instead of right after u_on_newpos() */
352 if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ)
355 /* when teleporting by scroll, we need to handle discovery
356 now before getting feedback about any objects at our
357 destination since we might land on another such scroll */
358 if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0))
359 learnscroll(telescroll);
361 telescroll = 0; /* no discovery by scrolltele()'s caller */
363 /* sequencing issue: we want guard's alarm, if any, to occur before
364 room entry message, if any, so need to check for vault exit prior
365 to spoteffects; but spoteffects() sets up new value for u.urooms
366 and vault code depends upon that value, so we need to fake it */
368 char save_urooms[5]; /* [sizeof u.urooms] */
370 Strcpy(save_urooms, u.urooms);
371 Strcpy(u.urooms, in_rooms(u.ux, u.uy, VAULT));
372 /* if hero has left vault, make guard notice */
373 if (!vault_occupied(u.urooms))
374 uleftvault(vault_guard);
375 Strcpy(u.urooms, save_urooms); /* reset prior to spoteffects() */
377 /* possible shop entry message comes after guard's shrill whistle */
379 invocation_message();
383 safe_teleds(allow_drag)
386 register int nux, nuy, tcnt = 0;
389 nux = rnd(COLNO - 1);
391 } while (!teleok(nux, nuy, (boolean) (tcnt > 200)) && ++tcnt <= 400);
394 teleds(nux, nuy, allow_drag);
403 register struct mkroom *croom = search_special(VAULT);
406 if (croom && somexy(croom, &c) && teleok(c.x, c.y, FALSE)) {
407 teleds(c.x, c.y, FALSE);
414 teleport_pet(mtmp, force_it)
415 register struct monst *mtmp;
418 register struct obj *otmp;
420 if (mtmp == u.usteed)
423 if (mtmp->mleashed) {
424 otmp = get_mleash(mtmp);
426 impossible("%s is leashed, without a leash.", Monnam(mtmp));
429 if (otmp->cursed && !force_it) {
434 Your("leash goes slack.");
436 Your("
\95R
\82Í
\82½
\82é
\82ñ
\82¾
\81D");
438 m_unleash(mtmp, FALSE);
445 /* teleport the hero via some method other than scroll of teleport */
449 (void) scrolltele((struct obj *) 0);
452 /* teleport the hero; return true if scroll of teleportation should become
453 discovered; teleds() will usually do the actual discovery, since the
454 outcome sometimes depends upon destination and discovery needs to be
455 performed before arrival, in case we land on another teleport scroll */
461 boolean result = FALSE; /* don't learn scroll */
463 /* Disable teleportation in stronghold && Vlad's Tower */
464 if (level.flags.noteleport) {
467 pline("A mysterious force prevents you from teleporting!");
469 pline("
\8aï
\96
\82È
\97Í
\82ª
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I");
474 /* don't show trap if "Sorry..." */
476 make_blinded(0L, FALSE);
478 if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
480 You_feel("disoriented for a moment.");
482 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
483 if (!wizard || yn("Override?") != 'y')
486 if ((Teleport_control && !Stunned) || wizard) {
489 pline("Being unconscious, you cannot control your teleport.");
491 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");
493 #if 0 /*JP*//*
\8eå
\8cê
\82ð
\8fÈ
\97ª
\82µ
\82Ä
\8aÈ
\97ª
\89»*/
496 Strcpy(whobuf, "you");
498 Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
499 pline("Where do %s want to be teleported?", whobuf);
501 pline("
\82Ç
\82Ì
\88Ê
\92u
\82É
\8fu
\8aÔ
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
506 if (getpos(&cc, TRUE, "the desired position") < 0)
508 if (getpos(&cc, TRUE, "
\88Ú
\93®
\82µ
\82½
\82¢
\8fê
\8f\8a") < 0)
509 return TRUE; /* abort */
510 /* possible extensions: introduce a small error if
511 magic power is low; allow transfer to solid rock */
512 if (teleok(cc.x, cc.y, FALSE)) {
513 /* for scroll, discover it regardless of destination */
516 teleds(cc.x, cc.y, FALSE);
522 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
525 } else if (scroll && scroll->blessed) {
526 /* (this used to be handled in seffects()) */
528 if (yn("Do you wish to teleport?") == 'n')
530 if (yn("
\8fu
\8aÔ
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H") == 'n')
536 (void) safe_teleds(FALSE);
537 /* teleds() will leave telescroll intact iff random destination
538 is far enough away for scroll discovery to be warranted */
541 telescroll = 0; /* reset */
545 /* ^T command; 'm ^T' == choose among several teleport modes */
549 long save_HTele, save_ETele;
550 int res, added, hidden;
551 boolean ignore_restrictions = FALSE;
552 /* also defined in spell.c */
556 #define UNHIDESPELL 3
557 #define REMOVESPELL 4
559 /* normal mode; ignore 'm' prefix if it was given */
561 return dotele(FALSE);
563 added = hidden = NOOP_SPELL;
564 save_HTele = HTeleportation, save_ETele = ETeleportation;
565 if (!iflags.menu_requested) {
566 ignore_restrictions = TRUE;
568 static const struct tporttypes {
570 const char *menudesc;
573 * Potential combinations:
574 * 1) attempt ^T without intrinsic, not know spell;
575 * 2) via intrinsic, not know spell, obey restrictions;
576 * 3) via intrinsic, not know spell, ignore restrictions;
577 * 4) via intrinsic, know spell, obey restrictions;
578 * 5) via intrinsic, know spell, ignore restrictions;
579 * 6) via spell, not have intrinsic, obey restrictions;
580 * 7) via spell, not have intrinsic, ignore restrictions;
581 * 8) force, obey other restrictions;
582 * 9) force, ignore restrictions.
583 * We only support the 1st (t), 2nd (n), 6th (s), and 9th (w).
585 * This ignores the fact that there is an experience level
586 * (or poly-form) requirement which might make normal ^T fail.
588 { 'n', "normal ^T on demand; no spell, obey restrictions" },
589 { 's', "via spellcast; no intrinsic teleport" },
590 { 't', "try ^T without having it; no spell" },
591 { 'w', "debug mode; ignore restrictions" }, /* trad wizard mode */
593 menu_item *picks = (menu_item *) 0;
598 win = create_nhwindow(NHW_MENU);
601 for (i = 0; i < SIZE(tports); ++i) {
602 any.a_int = (int) tports[i].menulet;
603 add_menu(win, NO_GLYPH, &any, (char) any.a_int, 0, ATR_NONE,
605 (tports[i].menulet == 'w') ? MENU_SELECTED
608 end_menu(win, "Which way do you want to teleport?");
609 i = select_menu(win, PICK_ONE, &picks);
610 destroy_nhwindow(win);
612 tmode = picks[0].item.a_int;
613 /* if we got 2, use the one which wasn't preselected */
614 if (i > 1 && tmode == 'w')
615 tmode = picks[1].item.a_int;
616 free((genericptr_t) picks);
618 /* preselected one was explicitly chosen and got toggled off */
625 HTeleportation |= I_SPECIAL; /* confer intrinsic teleportation */
626 hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
629 HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
630 added = tport_spell(ADD_SPELL); /* add teleport-away */
633 HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
634 hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
637 ignore_restrictions = TRUE;
642 /* if dotele() can be fatal, final disclosure might lie about
643 intrinsic teleportation; we should be able to live with that
644 since the menu finagling is only applicable in wizard mode */
645 res = dotele(ignore_restrictions);
647 HTeleportation = save_HTele;
648 ETeleportation = save_ETele;
649 if (added != NOOP_SPELL || hidden != NOOP_SPELL)
650 /* can't both be non-NOOP so addition will yield the non-NOOP one */
651 (void) tport_spell(added + hidden - NOOP_SPELL);
657 dotele(break_the_rules)
658 boolean break_the_rules; /* True: wizard mode ^T */
661 const char *cantdoit;
662 boolean trap_once = FALSE;
664 trap = t_at(u.ux, u.uy);
665 if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
669 trap_once = trap->once; /* trap may get deleted, save this */
672 pline("This is a vault teleport, usable once only.");
674 pline("
\88ê
\93x
\82©
\82¬
\82è
\82Ì
\91q
\8cÉ
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82¾
\81D");
676 if (yn("Jump in?") == 'n') {
678 if (yn("
\94ò
\82Ñ
\8d\9e\82Þ
\81H") == 'n') {
687 You("%s onto the teleportation trap.",
688 locomotion(youmonst.data, "jump"));
690 You("
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82É
\94ò
\82Ñ
\82±
\82ñ
\82¾
\81D");
694 boolean castit = FALSE;
695 register int sp_no = 0, energy = 0;
697 if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
698 && !can_teleport(youmonst.data))) {
699 /* Try to use teleport away spell.
700 3.6.2: this used to require that you know the spellbook
701 (probably just intended as an optimization to skip the
702 lookup loop) but it is possible to know and cast a spell
703 after forgetting its book due to amnesia. */
704 for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
705 if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY)
707 /* casting isn't inhibited by being Stunned (...it ought to be) */
708 castit = (sp_no < MAXSPELL && !Confusion);
709 if (!castit && !break_the_rules) {
712 !Teleportation ? ((sp_no < MAXSPELL)
713 ? "can't cast that spell"
714 : "don't know that spell")
715 : "are not able to teleport at will");
718 !Teleportation ? ((sp_no < MAXSPELL)
719 ? "
\82»
\82Ì
\96\82\96@
\82Í
\8f¥
\82¦
\82ç
\82ê
\82È
\82¢"
720 : "
\82»
\82ñ
\82È
\96\82\96@
\82Í
\92m
\82ç
\82È
\82¢")
721 : "
\8e©
\95ª
\82Ì
\88Ó
\8ev
\82Å
\8fu
\8aÔ
\88Ú
\93®
\82Å
\82«
\82È
\82¢");
728 /* 3.6.2: the magic numbers for hunger, strength, and energy
729 have been changed to match the ones used in spelleffects().
730 Also, failing these tests used to return 1 and use a move
731 even though casting failure due to these reasons doesn't.
732 [Note: this spellev() is different from the one in spell.c
733 but they both yield the same result.] */
734 #define spellev(spell_otyp) ((int) objects[spell_otyp].oc_level)
735 energy = 5 * spellev(SPE_TELEPORT_AWAY);
736 if (break_the_rules) {
739 /* spell will cost more if carrying the Amulet, but the
740 amount is rnd(2 * energy) so we can't know by how much;
741 average is twice the normal cost, but could be triple;
742 the extra energy is spent even if that results in not
743 having enough to cast (which also uses the move) */
744 else if (u.uen < energy)
746 } else if (u.uhunger <= 10) {
748 cantdoit = "are too weak from hunger";
750 cantdoit = "
\82É
\82Í
\82¨
\82È
\82©
\82ª
\8bó
\82«
\82·
\82¬
\82Ä
\82¢
\82é";
751 } else if (ACURR(A_STR) < 4) {
753 cantdoit = "lack the strength";
755 cantdoit = "
\82¾
\82¯
\82Ì
\97Í
\82ª
\82È
\82¢";
756 } else if (energy > u.uen) {
758 cantdoit = "lack the energy";
760 cantdoit = "
\82¾
\82¯
\82Ì
\83G
\83l
\83\8b\83M
\81[
\82ª
\82È
\82¢";
764 You("%s %s.", cantdoit,
765 castit ? "for a teleport spell" : "to teleport");
767 You("%s%s
\81D", cantdoit,
768 castit ? "
\8fu
\8aÔ
\88Ú
\93®
\82Ì
\96\82\96@
\82ð
\8f¥
\82¦
\82é" : "
\8fu
\8aÔ
\88Ú
\93®
\82·
\82é");
771 } else if (check_capacity(
773 "Your concentration falters from carrying so much.")) {
775 "
\91ò
\8eR
\82à
\82Ì
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\8fW
\92\86\82Å
\82«
\82È
\82¢
\81D")) {
776 return 1; /* this failure in spelleffects() also uses the move */
780 /* energy cost is deducted in spelleffects() */
781 exercise(A_WIS, TRUE);
782 if (spelleffects(sp_no, TRUE))
784 else if (!break_the_rules)
787 /* bypassing spelleffects(); apply energy cost directly */
794 if (trap && trap_once)
800 You("%s", shudder_for_moment);
813 const char *escape_by_flying = 0; /* when surviving dest of -N */
815 boolean force_dest = FALSE;
817 if (iflags.debug_fuzzer)
818 goto random_levtport;
819 if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
822 You_feel("very disoriented for a moment.");
824 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82È
\8bC
\82ª
\82µ
\82½
\81D");
827 if ((Teleport_control && !Stunned) || wizard) {
832 Strcpy(qbuf, "To what level do you want to teleport?");
834 Strcpy(qbuf, "
\89½
\8aK
\82É
\88Ú
\93®
\82µ
\82Ü
\82·
\82©
\81H");
836 if (iflags.menu_requested) {
837 /* wizard mode 'm ^V' skips prompting on first pass
838 (note: level Tport via menu won't have any second pass) */
839 iflags.menu_requested = FALSE;
846 Strcat(qbuf, " [type a number, name, or ? for a menu]");
848 Strcat(qbuf, " [
\90\94\8e\9a\82©
\96¼
\91O
\82ð
\82¢
\82ê
\82Ä
\82Ë
\81D?
\82Å
\83\81\83j
\83\85\81[]");
851 Strcat(qbuf, " [type a number or name]");
853 Strcat(qbuf, " [
\90\94\8e\9a\82©
\96¼
\91O
\82ð
\82¢
\82ê
\82Ä
\82Ë]");
855 *buf = '\0'; /* EDIT_GETLIN: if we're on second or later pass,
856 the previous input was invalid so don't use it
857 as getlin()'s preloaded default answer */
859 if (!strcmp(buf, "\033")) { /* cancelled */
860 if (Confusion && rnl(5)) {
864 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
865 goto random_levtport;
868 } else if (!strcmp(buf, "*")) {
869 goto random_levtport;
870 } else if (Confusion && rnl(5)) {
874 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
875 goto random_levtport;
877 if (wizard && !strcmp(buf, "?")) {
884 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
888 newlevel.dnum = destdnum;
889 newlevel.dlevel = destlev;
890 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
894 && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
896 /* ordinarily we'd use hold_another_object()
897 for something like this, but we don't want
898 fumbling or already full pack to interfere */
900 prinv("Endgame prerequisite:", amu, 0L);
904 } else if ((newlev = lev_by_name(buf)) == 0)
906 } while (!newlev && !digit(buf[0])
907 && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
909 /* no dungeon escape via this route */
912 goto random_levtport;
914 if (ynq("Go to Nowhere. Are you sure?") != 'y')
916 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')
919 You("%s in agony as your body begins to warp...",
920 is_silent(youmonst.data) ? "writhe" : "scream");
922 You("
\91Ì
\82ª
\88Ú
\93®
\82µ
\82Í
\82¶
\82ß
\82é
\82Æ
\81C
\8bê
\82µ
\82Ý%s
\81D
\81D
\81D",
923 is_silent(youmonst.data) ? "
\82Å
\90g
\82à
\82¾
\82¦
\82µ
\82½" : "
\82Ì
\82 \82¦
\82¬
\90º
\82ð
\8fo
\82µ
\82½");
925 display_nhwindow(WIN_MESSAGE, FALSE);
927 You("cease to exist.");
929 Your("
\91¶
\8dÝ
\82Í
\8fÁ
\96Å
\82µ
\82½
\81D");
932 Your("possessions land on the %s with a thud.",
934 Your("
\8e\9d\82¿
\82à
\82Ì
\82Í
\83h
\83T
\83b
\82Æ%s
\82É
\97\8e\82¿
\82½
\81D",
935 surface(u.ux, u.uy));
936 killer.format = NO_KILLER_PREFIX;
938 Strcpy(killer.name, "committed suicide");
940 Strcpy(killer.name, "
\8e©
\8eE
\82µ
\82½");
943 pline("An energized cloud of dust begins to coalesce.");
945 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");
947 Your("body rematerializes%s.",
948 invent ? ", and you gather up all your possessions" : "");
950 Your("
\91Ì
\82Í
\8dÄ
\82Ñ
\8eÀ
\91Ì
\89»
\82µ
\82½
\81D%s",
951 invent ? "
\82»
\82µ
\82Ä
\91S
\82Ä
\82Ì
\8e\9d\82¿
\95¨
\82ð
\8fE
\82¢
\8fã
\82°
\82½
\81D" : "");
956 /* if in Knox and the requested level > 0, stay put.
957 * we let negative values requests fall into the "heaven" loop.
959 if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
960 You1(shudder_for_moment);
963 /* if in Quest, the player sees "Home 1", etc., on the status
964 * line, instead of the logical depth of the level. controlled
965 * level teleport request is likely to be relativized to the
966 * status line, and consequently it should be incremented to
967 * the value of the logical depth of the target level.
969 * we let negative values requests fall into the "heaven" loop.
971 if (In_quest(&u.uz) && newlev > 0)
972 newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
973 } else { /* involuntary level tele */
975 newlev = random_teleport_level();
976 if (newlev == depth(&u.uz)) {
977 You1(shudder_for_moment);
982 if (u.utrap && u.utraptype == TT_BURIEDBALL)
983 buried_ball_to_punishment();
985 if (!next_to_u() && !force_dest) {
986 You1(shudder_for_moment);
989 if (In_endgame(&u.uz)) { /* must already be wizard */
990 int llimit = dunlevs_in_dungeon(&u.uz);
992 if (newlev >= 0 || newlev <= -llimit) {
994 You_cant("get there from here.");
996 You("
\82»
\82±
\82É
\82Í
\8ds
\82¯
\82È
\82¢
\81D");
999 newlevel.dnum = u.uz.dnum;
1000 newlevel.dlevel = llimit + newlev;
1001 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1005 killer.name[0] = 0; /* still alive, so far... */
1007 if (iflags.debug_fuzzer && newlev < 0)
1008 goto random_levtport;
1009 if (newlev < 0 && !force_dest) {
1011 /* take unpaid inventory items off of shop bills */
1012 in_mklev = TRUE; /* suppress map update */
1013 u_left_shop(u.ushops0, TRUE);
1014 /* you're now effectively out of the shop */
1015 *u.ushops0 = *u.ushops = '\0';
1018 if (newlev <= -10) {
1020 You("arrive in heaven.");
1022 You("
\93V
\8d\91\82É
\92H
\82è
\82Â
\82¢
\82½
\81D");
1024 verbalize("Thou art early, but we'll admit thee.");
1026 verbalize("
\93ð
\81C
\8e\80\82Ê
\82É
\82Í
\91\81\82·
\82¬
\82é
\82ª
\82»
\82ê
\82à
\82æ
\82©
\82ë
\82¤
\81D");
1027 killer.format = NO_KILLER_PREFIX;
1029 Strcpy(killer.name, "went to heaven prematurely");
1031 Strcpy(killer.name, "
\8eá
\82
\82µ
\82Ä
\93V
\8d\91\82É
\8ds
\82Á
\82½");
1032 } else if (newlev == -9) {
1034 You_feel("deliriously happy.");
1036 You("
\8b¶
\82Á
\82½
\82æ
\82¤
\82È
\8dK
\82¹
\82ð
\8a´
\82¶
\82½
\81D");
1038 pline("(In fact, you're on Cloud 9!)");
1040 pline("(
\96{
\93\96\82É
\8bê
\82ð
\8fæ
\82è
\89z
\82¦
\82½
\8fê
\8f\8a\82É
\82¢
\82é
\81I) ");
1041 display_nhwindow(WIN_MESSAGE, FALSE);
1044 You("are now high above the clouds...");
1046 You("
\89_
\82Ì
\97y
\82©
\8fã
\82É
\82¢
\82é
\81D
\81D
\81D");
1048 if (killer.name[0]) {
1049 ; /* arrival in heaven is pending */
1050 } else if (Levitation) {
1052 escape_by_flying = "float gently down to earth";
1054 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
1055 } else if (Flying) {
1057 escape_by_flying = "fly down to the ground";
1059 escape_by_flying = "
\82ä
\82Á
\82
\82è
\92n
\96Ê
\82É
\8d~
\82è
\82½
\81D";
1062 pline("Unfortunately, you don't know how to fly.");
1064 pline("
\8ec
\94O
\82È
\82ª
\82ç
\81C
\82 \82È
\82½
\82Í
\94ò
\82Ñ
\82©
\82½
\82ð
\92m
\82ç
\82È
\82¢
\81D");
1066 You("plummet a few thousand feet to your death.");
1068 pline("
\90\94\90ç
\83t
\83B
\81[
\83g
\82Ì
\8e\80\82Ì
\83_
\83C
\83r
\83\93\83O
\82¾
\81I");
1070 Sprintf(killer.name,
1071 "teleported out of the dungeon and fell to %s death",
1073 killer.format = NO_KILLER_PREFIX;
1075 Strcpy(killer.name, "
\96À
\8b{
\82ð
\94ò
\82Ñ
\82¾
\82µ
\83_
\83C
\83r
\83\93\83O
\82µ
\82Ä");
1076 killer.format = KILLED_BY;
1081 if (killer.name[0]) { /* the chosen destination was not survivable */
1084 /* set specific death location; this also suppresses bones */
1085 lsav = u.uz; /* save current level, see below */
1086 u.uz.dnum = 0; /* main dungeon */
1087 u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */
1089 /* can only get here via life-saving (or declining to die in
1090 explore|debug mode); the hero has now left the dungeon... */
1092 escape_by_flying = "find yourself back on the surface";
1094 escape_by_flying = "
\8bC
\82ª
\82Â
\82¢
\82½
\82ç
\92n
\8fã
\82É
\96ß
\82Á
\82Ä
\82¢
\82½";
1095 u.uz = lsav; /* restore u.uz so escape code works */
1098 /* calls done(ESCAPED) if newlevel==0 */
1099 if (escape_by_flying) {
1101 You("%s.", escape_by_flying);
1103 You("%s
\81D", escape_by_flying);
1104 newlevel.dnum = 0; /* specify main dungeon */
1105 newlevel.dlevel = 0; /* escape the dungeon */
1106 /* [dlevel used to be set to 1, but it doesn't make sense to
1107 teleport out of the dungeon and float or fly down to the
1108 surface but then actually arrive back inside the dungeon] */
1109 } else if (u.uz.dnum == medusa_level.dnum
1110 && newlev >= dungeons[u.uz.dnum].depth_start
1111 + dunlevs_in_dungeon(&u.uz)) {
1112 if (!(wizard && force_dest))
1113 find_hell(&newlevel);
1115 /* if invocation did not yet occur, teleporting into
1116 * the last level of Gehennom is forbidden.
1118 if (!wizard && Inhell && !u.uevent.invoked
1119 && newlev >= (dungeons[u.uz.dnum].depth_start
1120 + dunlevs_in_dungeon(&u.uz) - 1)) {
1121 newlev = dungeons[u.uz.dnum].depth_start
1122 + dunlevs_in_dungeon(&u.uz) - 2;
1126 pline("
\82¨
\82Á
\82Æ
\81D
\81D
\81D");
1128 /* no teleporting out of quest dungeon */
1129 if (In_quest(&u.uz) && newlev < depth(&qstart_level))
1130 newlev = depth(&qstart_level);
1131 /* the player thinks of levels purely in logical terms, so
1132 * we must translate newlev to a number relative to the
1135 if (!(wizard && force_dest))
1136 get_level(&newlevel, newlev);
1138 schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1139 /* in case player just read a scroll and is about to be asked to
1140 call it something, we can't defer until the end of the turn */
1141 if (u.utotype && !context.mon_moving)
1147 register struct trap *ttmp;
1149 struct d_level target_level;
1151 if (u.utrap && u.utraptype == TT_BURIEDBALL)
1152 buried_ball_to_punishment();
1155 You1(shudder_for_moment);
1159 /* if landed from another portal, do nothing */
1160 /* problem: level teleport landing escapes the check */
1161 if (!on_level(&u.uz, &u.uz0))
1165 You("activated a magic portal!");
1167 pline("
\96\82\96@
\82Ì
\93ü
\8cû
\82ª
\8dì
\93®
\82µ
\82½
\81I");
1169 /* prevent the poor shnook, whose amulet was stolen while in
1170 * the endgame, from accidently triggering the portal to the
1171 * next level, and thus losing the game
1173 if (In_endgame(&u.uz) && !u.uhave.amulet) {
1175 You_feel("dizzy for a moment, but nothing happens...");
1177 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");
1181 target_level = ttmp->dst;
1182 schedule_goto(&target_level, FALSE, FALSE, 1,
1184 "You feel dizzy for a moment, but the sensation passes.",
1186 "
\88ê
\8fu
\82ß
\82Ü
\82¢
\82ð
\8a´
\82¶
\82½
\81C
\82µ
\82©
\82µ
\82»
\82Ì
\8a´
\8ao
\82Í
\8fÁ
\82¦
\82½
\81D",
1194 if (In_endgame(&u.uz) || Antimagic) {
1196 shieldeff(u.ux, u.uy);
1198 You_feel("a wrenching sensation.");
1200 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1201 } else if (!next_to_u()) {
1202 You1(shudder_for_moment);
1203 } else if (trap->once) {
1205 newsym(u.ux, u.uy); /* get rid of trap symbol */
1212 level_tele_trap(trap, trflags)
1217 char verbbuf[BUFSZ];
1219 if ((trflags & VIASITTING) != 0)
1220 Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1222 Sprintf(verbbuf, "%s onto",
1223 Levitation ? (const char *) "float"
1224 : locomotion(youmonst.data, "step"));
1225 You("%s a level teleport trap!", verbbuf);
1227 if ((trflags & VIASITTING) != 0) {
1228 pline("
\95Ê
\82Ì
\8aK
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82ª
\94
\93®
\82µ
\82½
\81I");
1230 You("
\95Ê
\82Ì
\8aK
\82Ö
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82Ìã©
\82ð%s
\81I",
1231 Levitation ? (const char *) "
\8c©
\89º
\82ë
\82µ
\82½"
1232 : jpast(locomotion(youmonst.data, "
\93¥
\82Þ")));
1237 shieldeff(u.ux, u.uy);
1239 if (Antimagic || In_endgame(&u.uz)) {
1241 You_feel("a wrenching sensation.");
1243 You("
\82Ë
\82¶
\82ç
\82ê
\82½
\82æ
\82¤
\82È
\8a´
\8ao
\82ð
\8a´
\82¶
\82½
\81D");
1248 You("are momentarily blinded by a flash of light.");
1250 You("
\82Ü
\82Î
\82ä
\82¢
\8cõ
\82Å
\88ê
\8fu
\96Ú
\82ª
\82
\82ç
\82ñ
\82¾
\81D");
1253 You("are momentarily disoriented.");
1255 You("
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\81D");
1257 newsym(u.ux, u.uy); /* get rid of trap symbol */
1261 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1263 rloc_pos_ok(x, y, mtmp)
1264 register int x, y; /* coordinates of candidate location */
1267 register int xx, yy;
1269 if (!goodpos(x, y, mtmp, 0))
1272 * Check for restricted areas present in some special levels.
1274 * `xx' is current column; if 0, then `yy' will contain flag bits
1275 * rather than row: bit #0 set => moving upwards; bit #1 set =>
1276 * inside the Wizard's tower.
1281 /* no current location (migrating monster arrival) */
1282 if (dndest.nlx && On_W_tower_level(&u.uz))
1283 return (((yy & 2) != 0)
1284 /* inside xor not within */
1285 ^ !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1286 dndest.nhx, dndest.nhy));
1287 if (updest.lx && (yy & 1) != 0) /* moving up */
1288 return (within_bounded_area(x, y, updest.lx, updest.ly,
1289 updest.hx, updest.hy)
1291 || !within_bounded_area(x, y, updest.nlx, updest.nly,
1292 updest.nhx, updest.nhy)));
1293 if (dndest.lx && (yy & 1) == 0) /* moving down */
1294 return (within_bounded_area(x, y, dndest.lx, dndest.ly,
1295 dndest.hx, dndest.hy)
1297 || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1298 dndest.nhx, dndest.nhy)));
1300 /* [try to] prevent a shopkeeper or temple priest from being
1301 sent out of his room (caller might resort to goodpos() if
1302 we report failure here, so this isn't full prevention) */
1303 if (mtmp->isshk && inhishop(mtmp)) {
1304 if (levl[x][y].roomno != ESHK(mtmp)->shoproom)
1306 } else if (mtmp->ispriest && inhistemple(mtmp)) {
1307 if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1310 /* current location is <xx,yy> */
1311 if (!tele_jump_ok(xx, yy, x, y))
1321 * Pulls a monster from its current position and places a monster at
1322 * a new x and y. If oldx is 0, then the monster was not in the
1323 * levels.monsters array. However, if oldx is 0, oldy may still have
1324 * a value because mtmp is a migrating_mon. Worm tails are always
1325 * placed randomly around the head of the worm.
1332 register int oldx = mtmp->mx, oldy = mtmp->my;
1333 boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1335 if (x == mtmp->mx && y == mtmp->my && m_at(x,y) == mtmp)
1336 return; /* that was easy */
1338 if (oldx) { /* "pick up" monster */
1342 remove_monster(oldx, oldy);
1343 newsym(oldx, oldy); /* update old location */
1347 memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
1348 place_monster(mtmp, x, y); /* put monster down */
1349 update_monster_region(mtmp);
1351 if (mtmp->wormno) /* now put down tail */
1352 place_worm_tail_randomly(mtmp, x, y);
1354 if (u.ustuck == mtmp) {
1363 newsym(x, y); /* update new location */
1364 set_apparxy(mtmp); /* orient monster */
1366 /* shopkeepers will only teleport if you zap them with a wand of
1367 teleportation or if they've been transformed into a jumpy monster;
1368 the latter only happens if you've attacked them with polymorph */
1369 if (resident_shk && !inhishop(mtmp))
1370 make_angry_shk(mtmp, oldx, oldy);
1373 /* place a monster at a random location, typically due to teleport */
1374 /* return TRUE if successful, FALSE if not */
1376 rloc(mtmp, suppress_impossible)
1377 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1378 boolean suppress_impossible;
1380 register int x, y, trycount;
1382 if (mtmp == u.usteed) {
1387 if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */
1388 if (!In_W_tower(u.ux, u.uy, &u.uz))
1389 x = xupstair, y = yupstair;
1390 else if (!xdnladder) /* bottom level of tower */
1391 x = xupladder, y = yupladder;
1393 x = xdnladder, y = ydnladder;
1394 /* if the wiz teleports away to heal, try the up staircase,
1395 to block the player's escaping before he's healed
1396 (deliberately use `goodpos' rather than `rloc_pos_ok' here) */
1397 if (goodpos(x, y, mtmp, 0))
1403 x = rn1(COLNO - 3, 2);
1405 if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1406 : goodpos(x, y, mtmp, 0))
1408 } while (++trycount < 1000);
1410 /* last ditch attempt to find a good place */
1411 for (x = 2; x < COLNO - 1; x++)
1412 for (y = 0; y < ROWNO; y++)
1413 if (goodpos(x, y, mtmp, 0))
1416 /* level either full of monsters or somehow faulty */
1417 if (!suppress_impossible)
1418 impossible("rloc(): couldn't relocate monster");
1422 rloc_to(mtmp, x, y);
1430 register struct mkroom *croom = search_special(VAULT);
1433 if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1434 rloc_to(mtmp, c.x, c.y);
1437 (void) rloc(mtmp, TRUE);
1444 if (level.flags.noteleport) {
1447 pline("A mysterious force prevents %s from teleporting!",
1450 pline("
\8aï
\96
\82È
\97Í
\82ª%s
\82Ì
\8fu
\8aÔ
\88Ú
\93®
\82ð
\96h
\82¢
\82¾
\81I",
1459 mtele_trap(mtmp, trap, in_sight)
1466 if (tele_restrict(mtmp))
1468 if (teleport_pet(mtmp, FALSE)) {
1469 /* save name with pre-movement visibility */
1470 monname = Monnam(mtmp);
1472 /* Note: don't remove the trap if a vault. Other-
1473 * wise the monster will be stuck there, since
1474 * the guard isn't going to come for it...
1479 (void) rloc(mtmp, TRUE);
1482 if (canseemon(mtmp))
1484 pline("%s seems disoriented.", monname);
1486 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D", monname);
1489 pline("%s suddenly disappears!", monname);
1491 pline("%s
\82Í
\93Ë
\91R
\8fÁ
\82¦
\82½
\81I", monname);
1497 /* return 0 if still on level, 3 if not */
1499 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1505 int tt = (trap ? trap->ttyp : NO_TRAP);
1507 if (mtmp == u.ustuck) /* probably a vortex */
1508 return 0; /* temporary? kludge */
1509 if (teleport_pet(mtmp, force_it)) {
1511 int migrate_typ = MIGR_RANDOM;
1514 if (Is_stronghold(&u.uz)) {
1515 assign_level(&tolevel, &valley_level);
1516 } else if (Is_botlevel(&u.uz)) {
1517 if (in_sight && trap->tseen)
1519 pline("%s avoids the %s.", Monnam(mtmp),
1520 (tt == HOLE) ? "hole" : "trap");
1522 pline("%s
\82Í%s
\82ð
\89ñ
\94ð
\82µ
\82½
\81D", Monnam(mtmp),
1523 (tt == HOLE) ? "
\8c\8a" : "ã©");
1527 get_level(&tolevel, depth(&u.uz) + 1);
1529 } else if (tt == MAGIC_PORTAL) {
1530 if (In_endgame(&u.uz)
1531 && (mon_has_amulet(mtmp) || is_home_elemental(mtmp->data))) {
1532 if (in_sight && mtmp->data->mlet != S_ELEMENTAL) {
1534 pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1536 pline("%s
\82ª
\88ê
\8fu
\8bP
\82¢
\82½
\82æ
\82¤
\82É
\8c©
\82¦
\82½
\81D", Monnam(mtmp));
1541 assign_level(&tolevel, &trap->dst);
1542 migrate_typ = MIGR_PORTAL;
1544 } else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
1547 if (mon_has_amulet(mtmp) || In_endgame(&u.uz)
1548 /* NO_TRAP is used when forcing a monster off the level;
1549 onscary(0,0,) is true for the Wizard, Riders, lawful
1550 minions, Angels of any alignment, shopkeeper or priest
1551 currently inside his or her own special room */
1552 || (tt == NO_TRAP && onscary(0, 0, mtmp))) {
1555 pline("%s seems very disoriented for a moment.",
1557 pline("%s
\82Í
\88ê
\8fu
\95û
\8cü
\8a´
\8ao
\82ð
\91å
\82«
\82
\8e¸
\82Á
\82½
\82æ
\82¤
\82¾
\81D",
1561 if (tt == NO_TRAP) {
1562 /* creature is being forced off the level to make room;
1563 it will try to return to this level (at a random spot
1564 rather than its current one) if the level is left by
1565 the hero and then revisited */
1566 assign_level(&tolevel, &u.uz);
1568 nlev = random_teleport_level();
1569 if (nlev == depth(&u.uz)) {
1572 pline("%s shudders for a moment.", Monnam(mtmp));
1574 pline("%s
\82Í
\88ê
\8fu
\90k
\82¦
\82½
\81D", Monnam(mtmp));
1577 get_level(&tolevel, nlev);
1580 impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
1586 pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1588 pline("
\93Ë
\91R%s
\82ª
\8e\8b\8aE
\82©
\82ç
\8fÁ
\82¦
\82½
\81D", mon_nam(mtmp));
1592 migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1593 return 3; /* no longer on this level */
1598 /* place object randomly, returns False if it's gone (eg broken) */
1601 register struct obj *obj;
1603 register xchar tx, ty, otx, oty;
1604 boolean restricted_fall;
1605 int try_limit = 4000;
1607 if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1608 if (revive_corpse(obj))
1612 obj_extract_self(obj);
1615 restricted_fall = (otx == 0 && dndest.lx);
1617 tx = rn1(COLNO - 3, 2);
1621 } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1623 && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1624 dndest.hx, dndest.hy)
1626 && within_bounded_area(tx, ty,
1627 dndest.nlx, dndest.nly,
1628 dndest.nhx, dndest.nhy))))
1629 /* on the Wizard Tower levels, objects inside should
1630 stay inside and objects outside should stay outside */
1631 || (dndest.nlx && On_W_tower_level(&u.uz)
1632 && within_bounded_area(tx, ty, dndest.nlx, dndest.nly,
1633 dndest.nhx, dndest.nhy)
1634 != within_bounded_area(otx, oty, dndest.nlx, dndest.nly,
1635 dndest.nhx, dndest.nhy)));
1638 if (flooreffects(obj, tx, ty, "fall")) {
1640 if (flooreffects(obj, tx, ty, "
\97\8e\82¿
\82é")) {
1642 } else if (otx == 0 && oty == 0) {
1643 ; /* fell through a trap door; no update of old loc needed */
1645 if (costly_spot(otx, oty)
1646 && (!costly_spot(tx, ty)
1647 || !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) {
1648 if (costly_spot(u.ux, u.uy)
1649 && index(u.urooms, *in_rooms(otx, oty, 0)))
1650 addtobill(obj, FALSE, FALSE, FALSE);
1652 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1654 newsym(otx, oty); /* update old location */
1656 place_object(obj, tx, ty);
1661 /* Returns an absolute depth */
1663 random_teleport_level()
1665 int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1667 /* [the endgame case can only occur in wizard mode] */
1668 if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1671 /* What I really want to do is as follows:
1672 * -- If in a dungeon that goes down, the new level is to be restricted
1673 * to [top of parent, bottom of current dungeon]
1674 * -- If in a dungeon that goes up, the new level is to be restricted
1675 * to [top of current dungeon, bottom of parent]
1676 * -- If in a quest dungeon or similar dungeon entered by portals,
1677 * the new level is to be restricted to [top of current dungeon,
1678 * bottom of current dungeon]
1679 * The current behavior is not as sophisticated as that ideal, but is
1680 * still better what we used to do, which was like this for players
1681 * but different for monsters for no obvious reason. Currently, we
1682 * must explicitly check for special dungeons. We check for Knox
1683 * above; endgame is handled in the caller due to its different
1684 * message ("disoriented").
1686 * 3.4.2: explicitly handle quest here too, to fix the problem of
1687 * monsters sometimes level teleporting out of it into main dungeon.
1688 * Also prevent monsters reaching the Sanctum prior to invocation.
1690 if (In_quest(&u.uz)) {
1691 int bottom = dunlevs_in_dungeon(&u.uz),
1692 qlocate_depth = qlocate_level.dlevel;
1694 /* if hero hasn't reached the middle locate level yet,
1695 no one can randomly teleport past it */
1696 if (dunlev_reached(&u.uz) < qlocate_depth)
1697 bottom = qlocate_depth;
1698 min_depth = dungeons[u.uz.dnum].depth_start;
1699 max_depth = bottom + (dungeons[u.uz.dnum].depth_start - 1);
1703 dunlevs_in_dungeon(&u.uz) + (dungeons[u.uz.dnum].depth_start - 1);
1704 /* can't reach Sanctum if the invocation hasn't been performed */
1705 if (Inhell && !u.uevent.invoked)
1709 /* Get a random value relative to the current dungeon */
1710 /* Range is 1 to current+3, current not counting */
1711 nlev = rn2(cur_depth + 3 - min_depth) + min_depth;
1712 if (nlev >= cur_depth)
1715 if (nlev > max_depth) {
1717 /* teleport up if already on bottom */
1718 if (Is_botlevel(&u.uz))
1721 if (nlev < min_depth) {
1723 if (nlev == cur_depth) {
1725 if (nlev > max_depth)
1732 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1733 return false iff the attempt fails */
1735 u_teleport_mon(mtmp, give_feedback)
1737 boolean give_feedback;
1741 if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1744 pline("%s resists your magic!", Monnam(mtmp));
1746 pline("%s
\82Í
\96\82\96@
\82ð
\96h
\82¢
\82¾
\81I", Monnam(mtmp));
1748 } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1751 You("are no longer inside %s!", mon_nam(mtmp));
1753 You("%s
\82Ì
\93à
\95\94\82©
\82ç
\92E
\8fo
\82µ
\82½
\81I", mon_nam(mtmp));
1755 (void) rloc(mtmp, TRUE);
1756 } else if (is_rider(mtmp->data) && rn2(13)
1757 && enexto(&cc, u.ux, u.uy, mtmp->data))
1758 rloc_to(mtmp, cc.x, cc.y);
1760 (void) rloc(mtmp, TRUE);