OSDN Git Service

5a56c4d6beb7e884b881700f610e64ab78a5abb8
[jnethack/source.git] / src / teleport.c
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. */
5
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. */
10
11 #include "hack.h"
12
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 *));
18
19 /* non-null when teleporting via having read this scroll */
20 STATIC_VAR struct obj *telescroll = 0;
21
22 /*
23  * Is (x,y) a good position of mtmp?  If mtmp is NULL, then is (x,y) good
24  * for an object?
25  *
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.
28  */
29 boolean
30 goodpos(x, y, mtmp, gpflags)
31 int x, y;
32 struct monst *mtmp;
33 unsigned gpflags;
34 {
35     struct permonst *mdat = (struct permonst *) 0;
36     boolean ignorewater = ((gpflags & MM_IGNOREWATER) != 0);
37
38     if (!isok(x, y))
39         return FALSE;
40
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.
45      * oh well.
46      */
47     if (mtmp != &youmonst && x == u.ux && y == u.uy
48         && (!u.usteed || mtmp != u.usteed))
49         return FALSE;
50
51     if (mtmp) {
52         struct monst *mtmp2 = m_at(x, y);
53
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.
63          */
64         if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
65             return FALSE;
66
67         mdat = mtmp->data;
68         if (is_pool(x, y) && !ignorewater) {
69             if (mtmp == &youmonst)
70                 return (Levitation || Flying || Wwalking || Swimming
71                         || Amphibious);
72             else
73                 return (is_floater(mdat) || is_flyer(mdat) || is_swimmer(mdat)
74                         || is_clinger(mdat));
75         } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
76             return FALSE;
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)));
83             else
84                 return (is_floater(mdat) || is_flyer(mdat)
85                         || likes_lava(mdat));
86         }
87         if (passes_walls(mdat) && may_passwall(x, y))
88             return TRUE;
89         if (amorphous(mdat) && closed_door(x, y))
90             return TRUE;
91     }
92     if (!accessible(x, y)) {
93         if (!(is_pool(x, y) && ignorewater))
94             return FALSE;
95     }
96
97     if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
98         return FALSE;
99     return TRUE;
100 }
101
102 /*
103  * "entity next to"
104  *
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.
109  */
110 boolean
111 enexto(cc, xx, yy, mdat)
112 coord *cc;
113 register xchar xx, yy;
114 struct permonst *mdat;
115 {
116     return enexto_core(cc, xx, yy, mdat, 0);
117 }
118
119 boolean
120 enexto_core(cc, xx, yy, mdat, entflags)
121 coord *cc;
122 register xchar xx, yy;
123 struct permonst *mdat;
124 unsigned entflags;
125 {
126 #define MAX_GOOD 15
127     coord good[MAX_GOOD], *good_ptr;
128     int x, y, range, i;
129     int xmin, xmax, ymin, ymax;
130     struct monst fakemon; /* dummy monster */
131
132     if (!mdat) {
133         debugpline0("enexto() called with null mdat");
134         /* default to player's original monster type */
135         mdat = &mons[u.umonster];
136     }
137     fakemon = zeromonst;
138     set_mon_data(&fakemon, mdat); /* set up for goodpos */
139
140     good_ptr = good;
141     range = 1;
142     /*
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.
145      */
146     do {
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);
151
152         for (x = xmin; x <= xmax; x++)
153             if (goodpos(x, ymin, &fakemon, entflags)) {
154                 good_ptr->x = x;
155                 good_ptr->y = ymin;
156                 /* beware of accessing beyond segment boundaries.. */
157                 if (good_ptr++ == &good[MAX_GOOD - 1])
158                     goto full;
159             }
160         for (x = xmin; x <= xmax; x++)
161             if (goodpos(x, ymax, &fakemon, entflags)) {
162                 good_ptr->x = x;
163                 good_ptr->y = ymax;
164                 /* beware of accessing beyond segment boundaries.. */
165                 if (good_ptr++ == &good[MAX_GOOD - 1])
166                     goto full;
167             }
168         for (y = ymin + 1; y < ymax; y++)
169             if (goodpos(xmin, y, &fakemon, entflags)) {
170                 good_ptr->x = xmin;
171                 good_ptr->y = y;
172                 /* beware of accessing beyond segment boundaries.. */
173                 if (good_ptr++ == &good[MAX_GOOD - 1])
174                     goto full;
175             }
176         for (y = ymin + 1; y < ymax; y++)
177             if (goodpos(xmax, y, &fakemon, entflags)) {
178                 good_ptr->x = xmax;
179                 good_ptr->y = y;
180                 /* beware of accessing beyond segment boundaries.. */
181                 if (good_ptr++ == &good[MAX_GOOD - 1])
182                     goto full;
183             }
184         range++;
185
186         /* return if we've grown too big (nothing is valid) */
187         if (range > ROWNO && range > COLNO)
188             return FALSE;
189     } while (good_ptr == good);
190
191 full:
192     i = rn2((int) (good_ptr - good));
193     cc->x = good[i].x;
194     cc->y = good[i].y;
195     return TRUE;
196 }
197
198 /*
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.)
202  */
203 STATIC_OVL boolean
204 tele_jump_ok(x1, y1, x2, y2)
205 int x1, y1, x2, y2;
206 {
207     if (!isok(x2, y2))
208         return FALSE;
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,
212                                 dndest.nhy)
213             && !within_bounded_area(x2, y2, dndest.nlx, dndest.nly,
214                                     dndest.nhx, dndest.nhy))
215             return FALSE;
216         /* and if outside, can't teleport inside */
217         if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
218                                  dndest.nhy)
219             && within_bounded_area(x2, y2, dndest.nlx, dndest.nly, dndest.nhx,
220                                    dndest.nhy))
221             return FALSE;
222     }
223     if (updest.nlx > 0) { /* ditto */
224         if (within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
225                                 updest.nhy)
226             && !within_bounded_area(x2, y2, updest.nlx, updest.nly,
227                                     updest.nhx, updest.nhy))
228             return FALSE;
229         if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
230                                  updest.nhy)
231             && within_bounded_area(x2, y2, updest.nlx, updest.nly, updest.nhx,
232                                    updest.nhy))
233             return FALSE;
234     }
235     return TRUE;
236 }
237
238 STATIC_OVL boolean
239 teleok(x, y, trapok)
240 register int x, y;
241 boolean trapok;
242 {
243     if (!trapok && t_at(x, y))
244         return FALSE;
245     if (!goodpos(x, y, &youmonst, 0))
246         return FALSE;
247     if (!tele_jump_ok(u.ux, u.uy, x, y))
248         return FALSE;
249     if (!in_out_region(x, y))
250         return FALSE;
251     return TRUE;
252 }
253
254 void
255 teleds(nux, nuy, allow_drag)
256 register int nux, nuy;
257 boolean allow_drag;
258 {
259     boolean ball_active, ball_still_in_range;
260     struct monst *vault_guard = vault_occupied(u.urooms) ? findgd() : 0;
261
262     if (u.utraptype == TT_BURIEDBALL) {
263         /* unearth it */
264         buried_ball_to_punishment();
265     }
266     ball_active = (Punished && uball->where != OBJ_FREE);
267     ball_still_in_range = FALSE;
268
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
274      * special cases:
275      *    0                          0
276      *   _X  move east       ----->  X_
277      *    @                           @
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.
283      */
284     if (ball_active) {
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 */
287         else {
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.
292                  */
293                 allow_drag = FALSE;
294                 unplacebc();
295             }
296         }
297     }
298     reset_utrap(FALSE);
299     u.ustuck = 0;
300     u.ux0 = u.ux;
301     u.uy0 = u.uy;
302
303     if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
304         /* mimics stop being unnoticed */
305         youmonst.m_ap_type = M_AP_NOTHING;
306     }
307
308     if (u.uswallow) {
309         u.uswldtim = u.uswallow = 0;
310         if (Punished && !ball_active) {
311             /* ensure ball placement, like unstuck */
312             ball_active = TRUE;
313             allow_drag = FALSE;
314         }
315         docrt();
316     }
317     if (ball_active) {
318         if (ball_still_in_range || allow_drag) {
319             int bc_control;
320             xchar ballx, bally, chainx, chainy;
321             boolean cause_delay;
322
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);
326         }
327     }
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);
332     if (ball_active) {
333         if (!ball_still_in_range && !allow_drag)
334             placebc();
335     }
336     initrack(); /* teleports mess up tracking monsters without this */
337     update_player_regions();
338     /*
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.
343      */
344     newsym(u.ux0, u.uy0);
345     see_monsters();
346     vision_full_recalc = 1;
347     nomul(0);
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)
353         switch_terrain();
354     if (telescroll) {
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);
360         else
361             telescroll = 0; /* no discovery by scrolltele()'s caller */
362     }
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 */
367     if (vault_guard) {
368         char save_urooms[5]; /* [sizeof u.urooms] */
369
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() */
376     }
377     /* possible shop entry message comes after guard's shrill whistle */
378     spoteffects(TRUE);
379     invocation_message();
380 }
381
382 boolean
383 safe_teleds(allow_drag)
384 boolean allow_drag;
385 {
386     register int nux, nuy, tcnt = 0;
387
388     do {
389         nux = rnd(COLNO - 1);
390         nuy = rn2(ROWNO);
391     } while (!teleok(nux, nuy, (boolean) (tcnt > 200)) && ++tcnt <= 400);
392
393     if (tcnt <= 400) {
394         teleds(nux, nuy, allow_drag);
395         return TRUE;
396     } else
397         return FALSE;
398 }
399
400 STATIC_OVL void
401 vault_tele()
402 {
403     register struct mkroom *croom = search_special(VAULT);
404     coord c;
405
406     if (croom && somexy(croom, &c) && teleok(c.x, c.y, FALSE)) {
407         teleds(c.x, c.y, FALSE);
408         return;
409     }
410     tele();
411 }
412
413 boolean
414 teleport_pet(mtmp, force_it)
415 register struct monst *mtmp;
416 boolean force_it;
417 {
418     register struct obj *otmp;
419
420     if (mtmp == u.usteed)
421         return FALSE;
422
423     if (mtmp->mleashed) {
424         otmp = get_mleash(mtmp);
425         if (!otmp) {
426             impossible("%s is leashed, without a leash.", Monnam(mtmp));
427             goto release_it;
428         }
429         if (otmp->cursed && !force_it) {
430             yelp(mtmp);
431             return FALSE;
432         } else {
433 /*JP
434             Your("leash goes slack.");
435 */
436             Your("\95R\82Í\82½\82é\82ñ\82¾\81D");
437         release_it:
438             m_unleash(mtmp, FALSE);
439             return TRUE;
440         }
441     }
442     return TRUE;
443 }
444
445 /* teleport the hero via some method other than scroll of teleport */
446 void
447 tele()
448 {
449     (void) scrolltele((struct obj *) 0);
450 }
451
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 */
456 boolean
457 scrolltele(scroll)
458 struct obj *scroll;
459 {
460     coord cc;
461     boolean result = FALSE; /* don't learn scroll */
462
463     /* Disable teleportation in stronghold && Vlad's Tower */
464     if (level.flags.noteleport) {
465         if (!wizard) {
466 /*JP
467             pline("A mysterious force prevents you from teleporting!");
468 */
469             pline("\8aï\96­\82È\97Í\82ª\8fu\8aÔ\88Ú\93®\82ð\96h\82¢\82¾\81I");
470             return TRUE;
471         }
472     }
473
474     /* don't show trap if "Sorry..." */
475     if (!Blinded)
476         make_blinded(0L, FALSE);
477
478     if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
479 /*JP
480         You_feel("disoriented for a moment.");
481 */
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')
484             return FALSE;
485     }
486     if ((Teleport_control && !Stunned) || wizard) {
487         if (unconscious()) {
488 /*JP
489             pline("Being unconscious, you cannot control your teleport.");
490 */
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");
492         } else {
493 #if 0 /*JP*//*\8eå\8cê\82ð\8fÈ\97ª\82µ\82Ä\8aÈ\97ª\89»*/
494             char whobuf[BUFSZ];
495
496             Strcpy(whobuf, "you");
497             if (u.usteed)
498                 Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
499             pline("Where do %s want to be teleported?", whobuf);
500 #else
501             pline("\82Ç\82Ì\88Ê\92u\82É\8fu\8aÔ\88Ú\93®\82µ\82Ü\82·\82©\81H");
502 #endif
503             cc.x = u.ux;
504             cc.y = u.uy;
505 /*JP
506             if (getpos(&cc, TRUE, "the desired position") < 0)
507 */
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 */
514                 if (scroll)
515                     learnscroll(scroll);
516                 teleds(cc.x, cc.y, FALSE);
517                 return TRUE;
518             }
519 /*JP
520             pline("Sorry...");
521 */
522             pline("\82¨\82Á\82Æ\81D\81D\81D");
523             result = TRUE;
524         }
525     } else if (scroll && scroll->blessed) {
526         /* (this used to be handled in seffects()) */
527 /*JP
528         if (yn("Do you wish to teleport?") == 'n')
529 */
530         if (yn("\8fu\8aÔ\88Ú\93®\82µ\82Ü\82·\82©\81H") == 'n')
531             return TRUE;
532         result = TRUE;
533     }
534
535     telescroll = scroll;
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 */
539     if (telescroll)
540         result = TRUE;
541     telescroll = 0; /* reset */
542     return result;
543 }
544
545 /* ^T command; 'm ^T' == choose among several teleport modes */
546 int
547 dotelecmd()
548 {
549     long save_HTele, save_ETele;
550     int res, added, hidden;
551     boolean ignore_restrictions = FALSE;
552 /* also defined in spell.c */
553 #define NOOP_SPELL  0
554 #define HIDE_SPELL  1
555 #define ADD_SPELL   2
556 #define UNHIDESPELL 3
557 #define REMOVESPELL 4
558
559     /* normal mode; ignore 'm' prefix if it was given */
560     if (!wizard)
561         return dotele(FALSE);
562
563     added = hidden = NOOP_SPELL;
564     save_HTele = HTeleportation, save_ETele = ETeleportation;
565     if (!iflags.menu_requested) {
566         ignore_restrictions = TRUE;
567     } else {
568         static const struct tporttypes {
569             char menulet;
570             const char *menudesc;
571         } tports[] = {
572             /*
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).
584              *
585              * This ignores the fact that there is an experience level
586              * (or poly-form) requirement which might make normal ^T fail.
587              */
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 */
592         };
593         menu_item *picks = (menu_item *) 0;
594         anything any;
595         winid win;
596         int i, tmode;
597
598         win = create_nhwindow(NHW_MENU);
599         start_menu(win);
600         any = zeroany;
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,
604                      tports[i].menudesc,
605                      (tports[i].menulet == 'w') ? MENU_SELECTED
606                                                 : MENU_UNSELECTED);
607         }
608         end_menu(win, "Which way do you want to teleport?");
609         i = select_menu(win, PICK_ONE, &picks);
610         destroy_nhwindow(win);
611         if (i > 0) {
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);
617         } else if (i == 0) {
618             /* preselected one was explicitly chosen and got toggled off */
619             tmode = 'w';
620         } else { /* ESC */
621             return 0;
622         }
623         switch (tmode) {
624         case 'n':
625             HTeleportation |= I_SPECIAL; /* confer intrinsic teleportation */
626             hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
627             break;
628         case 's':
629             HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
630             added = tport_spell(ADD_SPELL); /* add teleport-away */
631             break;
632         case 't':
633             HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
634             hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
635             break;
636         case 'w':
637             ignore_restrictions = TRUE;
638             break;
639         }
640     }
641
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);
646
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);
652
653     return res;
654 }
655
656 int
657 dotele(break_the_rules)
658 boolean break_the_rules; /* True: wizard mode ^T */
659 {
660     struct trap *trap;
661     const char *cantdoit;
662     boolean trap_once = FALSE;
663
664     trap = t_at(u.ux, u.uy);
665     if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
666         trap = 0;
667
668     if (trap) {
669         trap_once = trap->once; /* trap may get deleted, save this */
670         if (trap->once) {
671 /*JP
672             pline("This is a vault teleport, usable once only.");
673 */
674             pline("\88ê\93x\82©\82¬\82è\82Ì\91q\8cÉ\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82¾\81D");
675 /*JP
676             if (yn("Jump in?") == 'n') {
677 */
678             if (yn("\94ò\82Ñ\8d\9e\82Þ\81H") == 'n') {
679                 trap = 0;
680             } else {
681                 deltrap(trap);
682                 newsym(u.ux, u.uy);
683             }
684         }
685         if (trap)
686 #if 0 /*JP*/
687             You("%s onto the teleportation trap.",
688                 locomotion(youmonst.data, "jump"));
689 #else
690             You("\8fu\8aÔ\88Ú\93®\82Ìã©\82É\94ò\82Ñ\82±\82ñ\82¾\81D");
691 #endif
692     }
693     if (!trap) {
694         boolean castit = FALSE;
695         register int sp_no = 0, energy = 0;
696
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)
706                     break;
707             /* casting isn't inhibited by being Stunned (...it ought to be) */
708             castit = (sp_no < MAXSPELL && !Confusion);
709             if (!castit && !break_the_rules) {
710 #if 0 /*JP*/
711                 You("%s.",
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");
716 #else
717                 You("%s\81D",
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¢");
722 #endif
723                 return 0;
724             }
725         }
726
727         cantdoit = 0;
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) {
737             if (!castit)
738                 energy = 0;
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)
745                 u.uen = energy;
746         } else if (u.uhunger <= 10) {
747 /*JP
748             cantdoit = "are too weak from hunger";
749 */
750             cantdoit = "\82É\82Í\82¨\82È\82©\82ª\8bó\82«\82·\82¬\82Ä\82¢\82é";
751         } else if (ACURR(A_STR) < 4) {
752 /*JP
753             cantdoit = "lack the strength";
754 */
755             cantdoit = "\82¾\82¯\82Ì\97Í\82ª\82È\82¢";
756         } else if (energy > u.uen) {
757 /*JP
758             cantdoit = "lack the energy";
759 */
760             cantdoit = "\82¾\82¯\82Ì\83G\83l\83\8b\83M\81[\82ª\82È\82¢";
761         }
762         if (cantdoit) {
763 #if 0 /*JP*/
764             You("%s %s.", cantdoit,
765                 castit ? "for a teleport spell" : "to teleport");
766 #else
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é");
769 #endif
770             return 0;
771         } else if (check_capacity(
772 /*JP
773                        "Your concentration falters from carrying so much.")) {
774 */
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 */
777         }
778
779         if (castit) {
780             /* energy cost is deducted in spelleffects() */
781             exercise(A_WIS, TRUE);
782             if (spelleffects(sp_no, TRUE))
783                 return 1;
784             else if (!break_the_rules)
785                 return 0;
786         } else {
787             /* bypassing spelleffects(); apply energy cost directly */
788             u.uen -= energy;
789             context.botl = 1;
790         }
791     }
792
793     if (next_to_u()) {
794         if (trap && trap_once)
795             vault_tele();
796         else
797             tele();
798         (void) next_to_u();
799     } else {
800         You("%s", shudder_for_moment);
801         return 0;
802     }
803     if (!trap)
804         morehungry(100);
805     return 1;
806 }
807
808 void
809 level_tele()
810 {
811     register int newlev;
812     d_level newlevel;
813     const char *escape_by_flying = 0; /* when surviving dest of -N */
814     char buf[BUFSZ];
815     boolean force_dest = FALSE;
816
817     if (iflags.debug_fuzzer)
818         goto random_levtport;
819     if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
820         && !wizard) {
821 /*JP
822         You_feel("very disoriented for a moment.");
823 */
824         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
825         return;
826     }
827     if ((Teleport_control && !Stunned) || wizard) {
828         char qbuf[BUFSZ];
829         int trycnt = 0;
830
831 /*JP
832         Strcpy(qbuf, "To what level do you want to teleport?");
833 */
834         Strcpy(qbuf, "\89½\8aK\82É\88Ú\93®\82µ\82Ü\82·\82©\81H");
835         do {
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;
840                 if (wizard)
841                     goto levTport_menu;
842             }
843             if (++trycnt == 2) {
844                 if (wizard)
845 /*JP
846                     Strcat(qbuf, " [type a number, name, or ? for a menu]");
847 */
848                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë\81D?\82Å\83\81\83j\83\85\81[]");
849                 else
850 /*JP
851                     Strcat(qbuf, " [type a number or name]");
852 */
853                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë]");
854             }
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 */
858             getlin(qbuf, buf);
859             if (!strcmp(buf, "\033")) { /* cancelled */
860                 if (Confusion && rnl(5)) {
861 /*JP
862                     pline("Oops...");
863 */
864                     pline("\82¨\82Á\82Æ\81D\81D\81D");
865                     goto random_levtport;
866                 }
867                 return;
868             } else if (!strcmp(buf, "*")) {
869                 goto random_levtport;
870             } else if (Confusion && rnl(5)) {
871 /*JP
872                 pline("Oops...");
873 */
874                 pline("\82¨\82Á\82Æ\81D\81D\81D");
875                 goto random_levtport;
876             }
877             if (wizard && !strcmp(buf, "?")) {
878                 schar destlev;
879                 xchar destdnum;
880
881             levTport_menu:
882                 destlev = 0;
883                 destdnum = 0;
884                 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
885                 if (!newlev)
886                     return;
887
888                 newlevel.dnum = destdnum;
889                 newlevel.dlevel = destlev;
890                 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
891                     struct obj *amu;
892
893                     if (!u.uhave.amulet
894                         && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
895                                != 0) {
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 */
899                         amu = addinv(amu);
900                         prinv("Endgame prerequisite:", amu, 0L);
901                     }
902                 }
903                 force_dest = TRUE;
904             } else if ((newlev = lev_by_name(buf)) == 0)
905                 newlev = atoi(buf);
906         } while (!newlev && !digit(buf[0])
907                  && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
908
909         /* no dungeon escape via this route */
910         if (newlev == 0) {
911             if (trycnt >= 10)
912                 goto random_levtport;
913 /*JP
914             if (ynq("Go to Nowhere.  Are you sure?") != 'y')
915 */
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')
917                 return;
918 #if 0 /*JP*/
919             You("%s in agony as your body begins to warp...",
920                 is_silent(youmonst.data) ? "writhe" : "scream");
921 #else
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½");
924 #endif
925             display_nhwindow(WIN_MESSAGE, FALSE);
926 /*JP
927             You("cease to exist.");
928 */
929             Your("\91\8dÝ\82Í\8fÁ\96Å\82µ\82½\81D");
930             if (invent)
931 /*JP
932                 Your("possessions land on the %s with a thud.",
933 */
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;
937 /*JP
938             Strcpy(killer.name, "committed suicide");
939 */
940             Strcpy(killer.name, "\8e©\8eE\82µ\82½");
941             done(DIED);
942 /*JP
943             pline("An energized cloud of dust begins to coalesce.");
944 */
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");
946 #if 0 /*JP*/
947             Your("body rematerializes%s.",
948                  invent ? ", and you gather up all your possessions" : "");
949 #else
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" : "");
952 #endif
953             return;
954         }
955
956         /* if in Knox and the requested level > 0, stay put.
957          * we let negative values requests fall into the "heaven" loop.
958          */
959         if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
960             You1(shudder_for_moment);
961             return;
962         }
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.
968          *
969          * we let negative values requests fall into the "heaven" loop.
970          */
971         if (In_quest(&u.uz) && newlev > 0)
972             newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
973     } else { /* involuntary level tele */
974     random_levtport:
975         newlev = random_teleport_level();
976         if (newlev == depth(&u.uz)) {
977             You1(shudder_for_moment);
978             return;
979         }
980     }
981
982     if (u.utrap && u.utraptype == TT_BURIEDBALL)
983         buried_ball_to_punishment();
984
985     if (!next_to_u() && !force_dest) {
986         You1(shudder_for_moment);
987         return;
988     }
989     if (In_endgame(&u.uz)) { /* must already be wizard */
990         int llimit = dunlevs_in_dungeon(&u.uz);
991
992         if (newlev >= 0 || newlev <= -llimit) {
993 /*JP
994             You_cant("get there from here.");
995 */
996             You("\82»\82±\82É\82Í\8ds\82¯\82È\82¢\81D");
997             return;
998         }
999         newlevel.dnum = u.uz.dnum;
1000         newlevel.dlevel = llimit + newlev;
1001         schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1002         return;
1003     }
1004
1005     killer.name[0] = 0; /* still alive, so far... */
1006
1007     if (iflags.debug_fuzzer && newlev < 0)
1008         goto random_levtport;
1009     if (newlev < 0 && !force_dest) {
1010         if (*u.ushops0) {
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';
1016             in_mklev = FALSE;
1017         }
1018         if (newlev <= -10) {
1019 /*JP
1020             You("arrive in heaven.");
1021 */
1022             You("\93V\8d\91\82É\92H\82è\82Â\82¢\82½\81D");
1023 /*JP
1024             verbalize("Thou art early, but we'll admit thee.");
1025 */
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;
1028 /*JP
1029             Strcpy(killer.name, "went to heaven prematurely");
1030 */
1031             Strcpy(killer.name, "\8eá\82­\82µ\82Ä\93V\8d\91\82É\8ds\82Á\82½");
1032         } else if (newlev == -9) {
1033 /*JP
1034             You_feel("deliriously happy.");
1035 */
1036             You("\8b\82Á\82½\82æ\82¤\82È\8dK\82¹\82ð\8a´\82\82½\81D");
1037 /*JP
1038             pline("(In fact, you're on Cloud 9!)");
1039 */
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);
1042         } else
1043 /*JP
1044             You("are now high above the clouds...");
1045 */
1046             You("\89_\82Ì\97y\82©\8fã\82É\82¢\82é\81D\81D\81D");
1047
1048         if (killer.name[0]) {
1049             ; /* arrival in heaven is pending */
1050         } else if (Levitation) {
1051 /*JP
1052             escape_by_flying = "float gently down to earth";
1053 */
1054             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1055         } else if (Flying) {
1056 /*JP
1057             escape_by_flying = "fly down to the ground";
1058 */
1059             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1060         } else {
1061 /*JP
1062             pline("Unfortunately, you don't know how to fly.");
1063 */
1064             pline("\8ec\94O\82È\82ª\82ç\81C\82 \82È\82½\82Í\94ò\82Ñ\82©\82½\82ð\92m\82ç\82È\82¢\81D");
1065 /*JP
1066             You("plummet a few thousand feet to your death.");
1067 */
1068             pline("\90\94\90ç\83t\83B\81[\83g\82Ì\8e\80\82Ì\83_\83C\83r\83\93\83O\82¾\81I");
1069 #if 0 /*JP*/
1070             Sprintf(killer.name,
1071                     "teleported out of the dungeon and fell to %s death",
1072                     uhis());
1073             killer.format = NO_KILLER_PREFIX;
1074 #else
1075             Strcpy(killer.name, "\96À\8b{\82ð\94ò\82Ñ\82¾\82µ\83_\83C\83r\83\93\83O\82µ\82Ä");
1076             killer.format = KILLED_BY;
1077 #endif
1078         }
1079     }
1080
1081     if (killer.name[0]) { /* the chosen destination was not survivable */
1082         d_level lsav;
1083
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 */
1088         done(DIED);
1089         /* can only get here via life-saving (or declining to die in
1090            explore|debug mode); the hero has now left the dungeon... */
1091 /*JP
1092         escape_by_flying = "find yourself back on the surface";
1093 */
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 */
1096     }
1097
1098     /* calls done(ESCAPED) if newlevel==0 */
1099     if (escape_by_flying) {
1100 /*JP
1101         You("%s.", escape_by_flying);
1102 */
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);
1114     } else {
1115         /* if invocation did not yet occur, teleporting into
1116          * the last level of Gehennom is forbidden.
1117          */
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;
1123 /*JP
1124             pline("Sorry...");
1125 */
1126             pline("\82¨\82Á\82Æ\81D\81D\81D");
1127         }
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
1133          * current dungeon.
1134          */
1135         if (!(wizard && force_dest))
1136             get_level(&newlevel, newlev);
1137     }
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)
1142         deferred_goto();
1143 }
1144
1145 void
1146 domagicportal(ttmp)
1147 register struct trap *ttmp;
1148 {
1149     struct d_level target_level;
1150
1151     if (u.utrap && u.utraptype == TT_BURIEDBALL)
1152         buried_ball_to_punishment();
1153
1154     if (!next_to_u()) {
1155         You1(shudder_for_moment);
1156         return;
1157     }
1158
1159     /* if landed from another portal, do nothing */
1160     /* problem: level teleport landing escapes the check */
1161     if (!on_level(&u.uz, &u.uz0))
1162         return;
1163
1164 /*JP
1165     You("activated a magic portal!");
1166 */
1167     pline("\96\82\96@\82Ì\93ü\8cû\82ª\8dì\93®\82µ\82½\81I");
1168
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
1172      */
1173     if (In_endgame(&u.uz) && !u.uhave.amulet) {
1174 /*JP
1175         You_feel("dizzy for a moment, but nothing happens...");
1176 */
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");
1178         return;
1179     }
1180
1181     target_level = ttmp->dst;
1182     schedule_goto(&target_level, FALSE, FALSE, 1,
1183 /*JP
1184                   "You feel dizzy for a moment, but the sensation passes.",
1185 */
1186                   "\88ê\8fu\82ß\82Ü\82¢\82ð\8a´\82\82½\81C\82µ\82©\82µ\82»\82Ì\8a´\8ao\82Í\8fÁ\82¦\82½\81D",
1187                   (char *) 0);
1188 }
1189
1190 void
1191 tele_trap(trap)
1192 struct trap *trap;
1193 {
1194     if (In_endgame(&u.uz) || Antimagic) {
1195         if (Antimagic)
1196             shieldeff(u.ux, u.uy);
1197 /*JP
1198         You_feel("a wrenching sensation.");
1199 */
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) {
1204         deltrap(trap);
1205         newsym(u.ux, u.uy); /* get rid of trap symbol */
1206         vault_tele();
1207     } else
1208         tele();
1209 }
1210
1211 void
1212 level_tele_trap(trap, trflags)
1213 struct trap *trap;
1214 unsigned trflags;
1215 {
1216 #if 0 /*JP*/
1217     char verbbuf[BUFSZ];
1218
1219     if ((trflags & VIASITTING) != 0)
1220         Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1221     else
1222         Sprintf(verbbuf, "%s onto",
1223                 Levitation ? (const char *) "float"
1224                            : locomotion(youmonst.data, "step"));
1225     You("%s a level teleport trap!", verbbuf);
1226 #else
1227     if ((trflags & VIASITTING) != 0) {
1228         pline("\95Ê\82Ì\8aK\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82ª\94­\93®\82µ\82½\81I");
1229     } else {
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Þ")));
1233     }
1234 #endif
1235
1236     if (Antimagic) {
1237         shieldeff(u.ux, u.uy);
1238     }
1239     if (Antimagic || In_endgame(&u.uz)) {
1240 /*JP
1241         You_feel("a wrenching sensation.");
1242 */
1243         You("\82Ë\82\82ç\82ê\82½\82æ\82¤\82È\8a´\8ao\82ð\8a´\82\82½\81D");
1244         return;
1245     }
1246     if (!Blind)
1247 /*JP
1248         You("are momentarily blinded by a flash of light.");
1249 */
1250         You("\82Ü\82Î\82ä\82¢\8cõ\82Å\88ê\8fu\96Ú\82ª\82­\82ç\82ñ\82¾\81D");
1251     else
1252 /*JP
1253         You("are momentarily disoriented.");
1254 */
1255         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
1256     deltrap(trap);
1257     newsym(u.ux, u.uy); /* get rid of trap symbol */
1258     level_tele();
1259 }
1260
1261 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1262 STATIC_OVL boolean
1263 rloc_pos_ok(x, y, mtmp)
1264 register int x, y; /* coordinates of candidate location */
1265 struct monst *mtmp;
1266 {
1267     register int xx, yy;
1268
1269     if (!goodpos(x, y, mtmp, 0))
1270         return FALSE;
1271     /*
1272      * Check for restricted areas present in some special levels.
1273      *
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.
1277      */
1278     xx = mtmp->mx;
1279     yy = mtmp->my;
1280     if (!xx) {
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)
1290                     && (!updest.nlx
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)
1296                     && (!dndest.nlx
1297                         || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1298                                                 dndest.nhx, dndest.nhy)));
1299     } else {
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)
1305                 return FALSE;
1306         } else if (mtmp->ispriest && inhistemple(mtmp)) {
1307             if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1308                 return FALSE;
1309         }
1310         /* current location is <xx,yy> */
1311         if (!tele_jump_ok(xx, yy, x, y))
1312             return FALSE;
1313     }
1314     /* <x,y> is ok */
1315     return TRUE;
1316 }
1317
1318 /*
1319  * rloc_to()
1320  *
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.
1326  */
1327 void
1328 rloc_to(mtmp, x, y)
1329 struct monst *mtmp;
1330 register int x, y;
1331 {
1332     register int oldx = mtmp->mx, oldy = mtmp->my;
1333     boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1334
1335     if (x == mtmp->mx && y == mtmp->my && m_at(x,y) == mtmp)
1336         return; /* that was easy */
1337
1338     if (oldx) { /* "pick up" monster */
1339         if (mtmp->wormno) {
1340             remove_worm(mtmp);
1341         } else {
1342             remove_monster(oldx, oldy);
1343             newsym(oldx, oldy); /* update old location */
1344         }
1345     }
1346
1347     memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
1348     place_monster(mtmp, x, y); /* put monster down */
1349     update_monster_region(mtmp);
1350
1351     if (mtmp->wormno) /* now put down tail */
1352         place_worm_tail_randomly(mtmp, x, y);
1353
1354     if (u.ustuck == mtmp) {
1355         if (u.uswallow) {
1356             u.ux = x;
1357             u.uy = y;
1358             docrt();
1359         } else
1360             u.ustuck = 0;
1361     }
1362
1363     newsym(x, y);      /* update new location */
1364     set_apparxy(mtmp); /* orient monster */
1365
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);
1371 }
1372
1373 /* place a monster at a random location, typically due to teleport */
1374 /* return TRUE if successful, FALSE if not */
1375 boolean
1376 rloc(mtmp, suppress_impossible)
1377 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1378 boolean suppress_impossible;
1379 {
1380     register int x, y, trycount;
1381
1382     if (mtmp == u.usteed) {
1383         tele();
1384         return TRUE;
1385     }
1386
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;
1392         else
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))
1398             goto found_xy;
1399     }
1400
1401     trycount = 0;
1402     do {
1403         x = rn1(COLNO - 3, 2);
1404         y = rn2(ROWNO);
1405         if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1406                              : goodpos(x, y, mtmp, 0))
1407             goto found_xy;
1408     } while (++trycount < 1000);
1409
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))
1414                 goto found_xy;
1415
1416     /* level either full of monsters or somehow faulty */
1417     if (!suppress_impossible)
1418         impossible("rloc(): couldn't relocate monster");
1419     return FALSE;
1420
1421 found_xy:
1422     rloc_to(mtmp, x, y);
1423     return TRUE;
1424 }
1425
1426 STATIC_OVL void
1427 mvault_tele(mtmp)
1428 struct monst *mtmp;
1429 {
1430     register struct mkroom *croom = search_special(VAULT);
1431     coord c;
1432
1433     if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1434         rloc_to(mtmp, c.x, c.y);
1435         return;
1436     }
1437     (void) rloc(mtmp, TRUE);
1438 }
1439
1440 boolean
1441 tele_restrict(mon)
1442 struct monst *mon;
1443 {
1444     if (level.flags.noteleport) {
1445         if (canseemon(mon))
1446 #if 0 /*JP*/
1447             pline("A mysterious force prevents %s from teleporting!",
1448                   mon_nam(mon));
1449 #else
1450             pline("\8aï\96­\82È\97Í\82ª%s\82Ì\8fu\8aÔ\88Ú\93®\82ð\96h\82¢\82¾\81I",
1451                   mon_nam(mon));
1452 #endif
1453         return TRUE;
1454     }
1455     return FALSE;
1456 }
1457
1458 void
1459 mtele_trap(mtmp, trap, in_sight)
1460 struct monst *mtmp;
1461 struct trap *trap;
1462 int in_sight;
1463 {
1464     char *monname;
1465
1466     if (tele_restrict(mtmp))
1467         return;
1468     if (teleport_pet(mtmp, FALSE)) {
1469         /* save name with pre-movement visibility */
1470         monname = Monnam(mtmp);
1471
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...
1475          */
1476         if (trap->once)
1477             mvault_tele(mtmp);
1478         else
1479             (void) rloc(mtmp, TRUE);
1480
1481         if (in_sight) {
1482             if (canseemon(mtmp))
1483 /*JP
1484                 pline("%s seems disoriented.", monname);
1485 */
1486                 pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\82æ\82¤\82¾\81D", monname);
1487             else
1488 /*JP
1489                 pline("%s suddenly disappears!", monname);
1490 */
1491                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", monname);
1492             seetrap(trap);
1493         }
1494     }
1495 }
1496
1497 /* return 0 if still on level, 3 if not */
1498 int
1499 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1500 struct monst *mtmp;
1501 struct trap *trap;
1502 boolean force_it;
1503 int in_sight;
1504 {
1505     int tt = (trap ? trap->ttyp : NO_TRAP);
1506
1507     if (mtmp == u.ustuck) /* probably a vortex */
1508         return 0;         /* temporary? kludge */
1509     if (teleport_pet(mtmp, force_it)) {
1510         d_level tolevel;
1511         int migrate_typ = MIGR_RANDOM;
1512
1513         if (is_hole(tt)) {
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)
1518 #if 0 /*JP*/
1519                     pline("%s avoids the %s.", Monnam(mtmp),
1520                           (tt == HOLE) ? "hole" : "trap");
1521 #else
1522                     pline("%s\82Í%s\82ð\89ñ\94ð\82µ\82½\81D", Monnam(mtmp),
1523                           (tt == HOLE) ? "\8c\8a" : "ã©");
1524 #endif
1525                 return 0;
1526             } else {
1527                 get_level(&tolevel, depth(&u.uz) + 1);
1528             }
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) {
1533 /*JP
1534                     pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1535 */
1536                     pline("%s\82ª\88ê\8fu\8bP\82¢\82½\82æ\82¤\82É\8c©\82¦\82½\81D", Monnam(mtmp));
1537                     seetrap(trap);
1538                 }
1539                 return 0;
1540             } else {
1541                 assign_level(&tolevel, &trap->dst);
1542                 migrate_typ = MIGR_PORTAL;
1543             }
1544         } else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
1545             int nlev;
1546
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))) {
1553                 if (in_sight)
1554 /*JP
1555                     pline("%s seems very disoriented for a moment.",
1556 */
1557                     pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82¾\81D",
1558                           Monnam(mtmp));
1559                 return 0;
1560             }
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);
1567             } else {
1568                 nlev = random_teleport_level();
1569                 if (nlev == depth(&u.uz)) {
1570                     if (in_sight)
1571 /*JP
1572                         pline("%s shudders for a moment.", Monnam(mtmp));
1573 */
1574                         pline("%s\82Í\88ê\8fu\90k\82¦\82½\81D", Monnam(mtmp));
1575                     return 0;
1576                 }
1577                 get_level(&tolevel, nlev);
1578             }
1579         } else {
1580             impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
1581             return 0;
1582         }
1583
1584         if (in_sight) {
1585 /*JP
1586             pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1587 */
1588             pline("\93Ë\91R%s\82ª\8e\8b\8aE\82©\82ç\8fÁ\82¦\82½\81D", mon_nam(mtmp));
1589             if (trap)
1590                 seetrap(trap);
1591         }
1592         migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1593         return 3; /* no longer on this level */
1594     }
1595     return 0;
1596 }
1597
1598 /* place object randomly, returns False if it's gone (eg broken) */
1599 boolean
1600 rloco(obj)
1601 register struct obj *obj;
1602 {
1603     register xchar tx, ty, otx, oty;
1604     boolean restricted_fall;
1605     int try_limit = 4000;
1606
1607     if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1608         if (revive_corpse(obj))
1609             return FALSE;
1610     }
1611
1612     obj_extract_self(obj);
1613     otx = obj->ox;
1614     oty = obj->oy;
1615     restricted_fall = (otx == 0 && dndest.lx);
1616     do {
1617         tx = rn1(COLNO - 3, 2);
1618         ty = rn2(ROWNO);
1619         if (!--try_limit)
1620             break;
1621     } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1622              || (restricted_fall
1623                  && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1624                                           dndest.hx, dndest.hy)
1625                      || (dndest.nlx
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)));
1636
1637 /*JP
1638     if (flooreffects(obj, tx, ty, "fall")) {
1639 */
1640     if (flooreffects(obj, tx, ty, "\97\8e\82¿\82é")) {
1641         return FALSE;
1642     } else if (otx == 0 && oty == 0) {
1643         ; /* fell through a trap door; no update of old loc needed */
1644     } else {
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);
1651             else
1652                 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1653         }
1654         newsym(otx, oty); /* update old location */
1655     }
1656     place_object(obj, tx, ty);
1657     newsym(tx, ty);
1658     return TRUE;
1659 }
1660
1661 /* Returns an absolute depth */
1662 int
1663 random_teleport_level()
1664 {
1665     int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1666
1667     /* [the endgame case can only occur in wizard mode] */
1668     if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1669         return cur_depth;
1670
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").
1685      * --KAA
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.
1689      */
1690     if (In_quest(&u.uz)) {
1691         int bottom = dunlevs_in_dungeon(&u.uz),
1692             qlocate_depth = qlocate_level.dlevel;
1693
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);
1700     } else {
1701         min_depth = 1;
1702         max_depth =
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)
1706             max_depth -= 1;
1707     }
1708
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)
1713         nlev++;
1714
1715     if (nlev > max_depth) {
1716         nlev = max_depth;
1717         /* teleport up if already on bottom */
1718         if (Is_botlevel(&u.uz))
1719             nlev -= rnd(3);
1720     }
1721     if (nlev < min_depth) {
1722         nlev = min_depth;
1723         if (nlev == cur_depth) {
1724             nlev += rnd(3);
1725             if (nlev > max_depth)
1726                 nlev = max_depth;
1727         }
1728     }
1729     return nlev;
1730 }
1731
1732 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1733    return false iff the attempt fails */
1734 boolean
1735 u_teleport_mon(mtmp, give_feedback)
1736 struct monst *mtmp;
1737 boolean give_feedback;
1738 {
1739     coord cc;
1740
1741     if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1742         if (give_feedback)
1743 /*JP
1744             pline("%s resists your magic!", Monnam(mtmp));
1745 */
1746             pline("%s\82Í\96\82\96@\82ð\96h\82¢\82¾\81I", Monnam(mtmp));
1747         return FALSE;
1748     } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1749         if (give_feedback)
1750 /*JP
1751             You("are no longer inside %s!", mon_nam(mtmp));
1752 */
1753             You("%s\82Ì\93à\95\94\82©\82ç\92E\8fo\82µ\82½\81I", mon_nam(mtmp));
1754         unstuck(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);
1759     else
1760         (void) rloc(mtmp, TRUE);
1761     return TRUE;
1762 }
1763
1764 /*teleport.c*/