OSDN Git Service

0af53c27d06bbe87a115da5aed5d33a00e67a0c8
[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\81D",
712                     !Teleportation ? ((sp_no < MAXSPELL)
713                                         ? "\82»\82Ì\96\82\96@\82Í\8f¥\82¦\82ç\82ê\82È\82¢"
714                                         : "\82»\82ñ\82È\96\82\96@\82Í\92m\82ç\82È\82¢")
715                                    : "\8e©\95ª\82Ì\88Ó\8ev\82Å\8fu\8aÔ\88Ú\93®\82Å\82«\82È\82¢");
716 #else
717 #endif
718                 return 0;
719             }
720         }
721
722         cantdoit = 0;
723         /* 3.6.2: the magic numbers for hunger, strength, and energy
724            have been changed to match the ones used in spelleffects().
725            Also, failing these tests used to return 1 and use a move
726            even though casting failure due to these reasons doesn't.
727            [Note: this spellev() is different from the one in spell.c
728            but they both yield the same result.] */
729 #define spellev(spell_otyp) ((int) objects[spell_otyp].oc_level)
730         energy = 5 * spellev(SPE_TELEPORT_AWAY);
731         if (break_the_rules) {
732             if (!castit)
733                 energy = 0;
734             /* spell will cost more if carrying the Amulet, but the
735                amount is rnd(2 * energy) so we can't know by how much;
736                average is twice the normal cost, but could be triple;
737                the extra energy is spent even if that results in not
738                having enough to cast (which also uses the move) */
739             else if (u.uen < energy)
740                 u.uen = energy;
741         } else if (u.uhunger <= 10) {
742 /*JP
743             cantdoit = "are too weak from hunger";
744 */
745             cantdoit = "\82É\82Í\82¨\82È\82©\82ª\8bó\82«\82·\82¬\82Ä\82¢\82é";
746         } else if (ACURR(A_STR) < 4) {
747 /*JP
748             cantdoit = "lack the strength";
749 */
750             cantdoit = "\82¾\82¯\82Ì\97Í\82ª\82È\82¢";
751         } else if (energy > u.uen) {
752 /*JP
753             cantdoit = "lack the energy";
754 */
755             cantdoit = "\82¾\82¯\82Ì\83G\83l\83\8b\83M\81[\82ª\82È\82¢";
756         }
757         if (cantdoit) {
758 #if 0 /*JP*/
759             You("%s %s.", cantdoit,
760                 castit ? "for a teleport spell" : "to teleport");
761 #else
762             You("%s%s\81D", cantdoit,
763                 castit ? "\8fu\8aÔ\88Ú\93®\82Ì\96\82\96@\82ð\8f¥\82¦\82é" : "\8fu\8aÔ\88Ú\93®\82·\82é");
764 #endif
765             return 0;
766         } else if (check_capacity(
767 /*JP
768                        "Your concentration falters from carrying so much.")) {
769 */
770                        "\91ò\8eR\82à\82Ì\82ð\8e\9d\82¿\82·\82¬\82Ä\8fW\92\86\82Å\82«\82È\82¢\81D")) {
771             return 1; /* this failure in spelleffects() also uses the move */
772         }
773
774         if (castit) {
775             /* energy cost is deducted in spelleffects() */
776             exercise(A_WIS, TRUE);
777             if (spelleffects(sp_no, TRUE))
778                 return 1;
779             else if (!break_the_rules)
780                 return 0;
781         } else {
782             /* bypassing spelleffects(); apply energy cost directly */
783             u.uen -= energy;
784             context.botl = 1;
785         }
786     }
787
788     if (next_to_u()) {
789         if (trap && trap_once)
790             vault_tele();
791         else
792             tele();
793         (void) next_to_u();
794     } else {
795         You("%s", shudder_for_moment);
796         return 0;
797     }
798     if (!trap)
799         morehungry(100);
800     return 1;
801 }
802
803 void
804 level_tele()
805 {
806     register int newlev;
807     d_level newlevel;
808     const char *escape_by_flying = 0; /* when surviving dest of -N */
809     char buf[BUFSZ];
810     boolean force_dest = FALSE;
811
812     if (iflags.debug_fuzzer)
813         goto random_levtport;
814     if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
815         && !wizard) {
816 /*JP
817         You_feel("very disoriented for a moment.");
818 */
819         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
820         return;
821     }
822     if ((Teleport_control && !Stunned) || wizard) {
823         char qbuf[BUFSZ];
824         int trycnt = 0;
825
826 /*JP
827         Strcpy(qbuf, "To what level do you want to teleport?");
828 */
829         Strcpy(qbuf, "\89½\8aK\82É\88Ú\93®\82µ\82Ü\82·\82©\81H");
830         do {
831             if (iflags.menu_requested) {
832                 /* wizard mode 'm ^V' skips prompting on first pass
833                    (note: level Tport via menu won't have any second pass) */
834                 iflags.menu_requested = FALSE;
835                 if (wizard)
836                     goto levTport_menu;
837             }
838             if (++trycnt == 2) {
839                 if (wizard)
840 /*JP
841                     Strcat(qbuf, " [type a number, name, or ? for a menu]");
842 */
843                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë\81D?\82Å\83\81\83j\83\85\81[]");
844                 else
845 /*JP
846                     Strcat(qbuf, " [type a number or name]");
847 */
848                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë]");
849             }
850             *buf = '\0'; /* EDIT_GETLIN: if we're on second or later pass,
851                             the previous input was invalid so don't use it
852                             as getlin()'s preloaded default answer */
853             getlin(qbuf, buf);
854             if (!strcmp(buf, "\033")) { /* cancelled */
855                 if (Confusion && rnl(5)) {
856 /*JP
857                     pline("Oops...");
858 */
859                     pline("\82¨\82Á\82Æ\81D\81D\81D");
860                     goto random_levtport;
861                 }
862                 return;
863             } else if (!strcmp(buf, "*")) {
864                 goto random_levtport;
865             } else if (Confusion && rnl(5)) {
866 /*JP
867                 pline("Oops...");
868 */
869                 pline("\82¨\82Á\82Æ\81D\81D\81D");
870                 goto random_levtport;
871             }
872             if (wizard && !strcmp(buf, "?")) {
873                 schar destlev;
874                 xchar destdnum;
875
876             levTport_menu:
877                 destlev = 0;
878                 destdnum = 0;
879                 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
880                 if (!newlev)
881                     return;
882
883                 newlevel.dnum = destdnum;
884                 newlevel.dlevel = destlev;
885                 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
886                     struct obj *amu;
887
888                     if (!u.uhave.amulet
889                         && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
890                                != 0) {
891                         /* ordinarily we'd use hold_another_object()
892                            for something like this, but we don't want
893                            fumbling or already full pack to interfere */
894                         amu = addinv(amu);
895                         prinv("Endgame prerequisite:", amu, 0L);
896                     }
897                 }
898                 force_dest = TRUE;
899             } else if ((newlev = lev_by_name(buf)) == 0)
900                 newlev = atoi(buf);
901         } while (!newlev && !digit(buf[0])
902                  && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
903
904         /* no dungeon escape via this route */
905         if (newlev == 0) {
906             if (trycnt >= 10)
907                 goto random_levtport;
908 /*JP
909             if (ynq("Go to Nowhere.  Are you sure?") != 'y')
910 */
911             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')
912                 return;
913 #if 0 /*JP*/
914             You("%s in agony as your body begins to warp...",
915                 is_silent(youmonst.data) ? "writhe" : "scream");
916 #else
917             You("\91Ì\82ª\88Ú\93®\82µ\82Í\82\82ß\82é\82Æ\81C\8bê\82µ\82Ý%s\81D\81D\81D",
918                 is_silent(youmonst.data) ? "\82Å\90g\82à\82¾\82¦\82µ\82½" : "\82Ì\82 \82¦\82¬\90º\82ð\8fo\82µ\82½");
919 #endif
920             display_nhwindow(WIN_MESSAGE, FALSE);
921 /*JP
922             You("cease to exist.");
923 */
924                 Your("\91\8dÝ\82Í\8fÁ\96Å\82µ\82½\81D");
925             if (invent)
926 /*JP
927                 Your("possessions land on the %s with a thud.",
928 */
929                 Your("\8e\9d\82¿\82à\82Ì\82Í\83h\83T\83b\82Æ%s\82É\97\8e\82¿\82½\81D",
930                      surface(u.ux, u.uy));
931             killer.format = NO_KILLER_PREFIX;
932 /*JP
933             Strcpy(killer.name, "committed suicide");
934 */
935             Strcpy(killer.name, "\8e©\8eE\82µ\82½");
936             done(DIED);
937 /*JP
938             pline("An energized cloud of dust begins to coalesce.");
939 */
940             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");
941 #if 0 /*JP*/
942             Your("body rematerializes%s.",
943                  invent ? ", and you gather up all your possessions" : "");
944 #else
945             Your("\91Ì\82Í\8dÄ\82Ñ\8eÀ\91Ì\89»\82µ\82½\81D%s",
946                  invent ? "\82»\82µ\82Ä\91S\82Ä\82Ì\8e\9d\82¿\95¨\82ð\8fE\82¢\8fã\82°\82½\81D" : "");
947 #endif
948             return;
949         }
950
951         /* if in Knox and the requested level > 0, stay put.
952          * we let negative values requests fall into the "heaven" loop.
953          */
954         if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
955             You1(shudder_for_moment);
956             return;
957         }
958         /* if in Quest, the player sees "Home 1", etc., on the status
959          * line, instead of the logical depth of the level.  controlled
960          * level teleport request is likely to be relativized to the
961          * status line, and consequently it should be incremented to
962          * the value of the logical depth of the target level.
963          *
964          * we let negative values requests fall into the "heaven" loop.
965          */
966         if (In_quest(&u.uz) && newlev > 0)
967             newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
968     } else { /* involuntary level tele */
969     random_levtport:
970         newlev = random_teleport_level();
971         if (newlev == depth(&u.uz)) {
972             You1(shudder_for_moment);
973             return;
974         }
975     }
976
977     if (u.utrap && u.utraptype == TT_BURIEDBALL)
978         buried_ball_to_punishment();
979
980     if (!next_to_u() && !force_dest) {
981         You1(shudder_for_moment);
982         return;
983     }
984     if (In_endgame(&u.uz)) { /* must already be wizard */
985         int llimit = dunlevs_in_dungeon(&u.uz);
986
987         if (newlev >= 0 || newlev <= -llimit) {
988 /*JP
989             You_cant("get there from here.");
990 */
991             You("\82»\82±\82É\82Í\8ds\82¯\82È\82¢\81D");
992             return;
993         }
994         newlevel.dnum = u.uz.dnum;
995         newlevel.dlevel = llimit + newlev;
996         schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
997         return;
998     }
999
1000     killer.name[0] = 0; /* still alive, so far... */
1001
1002     if (iflags.debug_fuzzer && newlev < 0)
1003         goto random_levtport;
1004     if (newlev < 0 && !force_dest) {
1005         if (*u.ushops0) {
1006             /* take unpaid inventory items off of shop bills */
1007             in_mklev = TRUE; /* suppress map update */
1008             u_left_shop(u.ushops0, TRUE);
1009             /* you're now effectively out of the shop */
1010             *u.ushops0 = *u.ushops = '\0';
1011             in_mklev = FALSE;
1012         }
1013         if (newlev <= -10) {
1014 /*JP
1015             You("arrive in heaven.");
1016 */
1017             You("\93V\8d\91\82É\92H\82è\82Â\82¢\82½\81D");
1018 /*JP
1019             verbalize("Thou art early, but we'll admit thee.");
1020 */
1021             verbalize("\93ð\81C\8e\80\82Ê\82É\82Í\91\81\82·\82¬\82é\82ª\82»\82ê\82à\82æ\82©\82ë\82¤\81D");
1022             killer.format = NO_KILLER_PREFIX;
1023 /*JP
1024             Strcpy(killer.name, "went to heaven prematurely");
1025 */
1026             Strcpy(killer.name, "\8eá\82­\82µ\82Ä\93V\8d\91\82É\8ds\82Á\82½");
1027         } else if (newlev == -9) {
1028 /*JP
1029             You_feel("deliriously happy.");
1030 */
1031             You("\8b\82Á\82½\82æ\82¤\82È\8dK\82¹\82ð\8a´\82\82½\81D");
1032 /*JP
1033             pline("(In fact, you're on Cloud 9!)");
1034 */
1035             pline("(\96{\93\96\82É\8bê\82ð\8fæ\82è\89z\82¦\82½\8fê\8f\8a\82É\82¢\82é\81I) ");
1036             display_nhwindow(WIN_MESSAGE, FALSE);
1037         } else
1038 /*JP
1039             You("are now high above the clouds...");
1040 */
1041             You("\89_\82Ì\97y\82©\8fã\82É\82¢\82é\81D\81D\81D");
1042
1043         if (killer.name[0]) {
1044             ; /* arrival in heaven is pending */
1045         } else if (Levitation) {
1046 /*JP
1047             escape_by_flying = "float gently down to earth";
1048 */
1049             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1050         } else if (Flying) {
1051 /*JP
1052             escape_by_flying = "fly down to the ground";
1053 */
1054             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1055         } else {
1056 /*JP
1057             pline("Unfortunately, you don't know how to fly.");
1058 */
1059             pline("\8ec\94O\82È\82ª\82ç\81C\82 \82È\82½\82Í\94ò\82Ñ\82©\82½\82ð\92m\82ç\82È\82¢\81D");
1060 /*JP
1061             You("plummet a few thousand feet to your death.");
1062 */
1063             pline("\90\94\90ç\83t\83B\81[\83g\82Ì\8e\80\82Ì\83_\83C\83r\83\93\83O\82¾\81I");
1064 #if 0 /*JP*/
1065             Sprintf(killer.name,
1066                     "teleported out of the dungeon and fell to %s death",
1067                     uhis());
1068             killer.format = NO_KILLER_PREFIX;
1069 #else
1070             Strcpy(killer.name, "\96À\8b{\82ð\94ò\82Ñ\82¾\82µ\83_\83C\83r\83\93\83O\82µ\82Ä");
1071             killer.format = KILLED_BY;
1072 #endif
1073         }
1074     }
1075
1076     if (killer.name[0]) { /* the chosen destination was not survivable */
1077         d_level lsav;
1078
1079         /* set specific death location; this also suppresses bones */
1080         lsav = u.uz;   /* save current level, see below */
1081         u.uz.dnum = 0; /* main dungeon */
1082         u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */
1083         done(DIED);
1084         /* can only get here via life-saving (or declining to die in
1085            explore|debug mode); the hero has now left the dungeon... */
1086 /*JP
1087         escape_by_flying = "find yourself back on the surface";
1088 */
1089         escape_by_flying = "\8bC\82ª\82Â\82¢\82½\82ç\92n\8fã\82É\96ß\82Á\82Ä\82¢\82½";
1090         u.uz = lsav; /* restore u.uz so escape code works */
1091     }
1092
1093     /* calls done(ESCAPED) if newlevel==0 */
1094     if (escape_by_flying) {
1095 /*JP
1096         You("%s.", escape_by_flying);
1097 */
1098         You("%s\81D", escape_by_flying);
1099         newlevel.dnum = 0;   /* specify main dungeon */
1100         newlevel.dlevel = 0; /* escape the dungeon */
1101         /* [dlevel used to be set to 1, but it doesn't make sense to
1102             teleport out of the dungeon and float or fly down to the
1103             surface but then actually arrive back inside the dungeon] */
1104     } else if (u.uz.dnum == medusa_level.dnum
1105                && newlev >= dungeons[u.uz.dnum].depth_start
1106                                 + dunlevs_in_dungeon(&u.uz)) {
1107         if (!(wizard && force_dest))
1108             find_hell(&newlevel);
1109     } else {
1110         /* if invocation did not yet occur, teleporting into
1111          * the last level of Gehennom is forbidden.
1112          */
1113         if (!wizard && Inhell && !u.uevent.invoked
1114             && newlev >= (dungeons[u.uz.dnum].depth_start
1115                           + dunlevs_in_dungeon(&u.uz) - 1)) {
1116             newlev = dungeons[u.uz.dnum].depth_start
1117                      + dunlevs_in_dungeon(&u.uz) - 2;
1118 /*JP
1119             pline("Sorry...");
1120 */
1121             pline("\82¨\82Á\82Æ\81D\81D\81D");
1122         }
1123         /* no teleporting out of quest dungeon */
1124         if (In_quest(&u.uz) && newlev < depth(&qstart_level))
1125             newlev = depth(&qstart_level);
1126         /* the player thinks of levels purely in logical terms, so
1127          * we must translate newlev to a number relative to the
1128          * current dungeon.
1129          */
1130         if (!(wizard && force_dest))
1131             get_level(&newlevel, newlev);
1132     }
1133     schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1134     /* in case player just read a scroll and is about to be asked to
1135        call it something, we can't defer until the end of the turn */
1136     if (u.utotype && !context.mon_moving)
1137         deferred_goto();
1138 }
1139
1140 void
1141 domagicportal(ttmp)
1142 register struct trap *ttmp;
1143 {
1144     struct d_level target_level;
1145
1146     if (u.utrap && u.utraptype == TT_BURIEDBALL)
1147         buried_ball_to_punishment();
1148
1149     if (!next_to_u()) {
1150         You1(shudder_for_moment);
1151         return;
1152     }
1153
1154     /* if landed from another portal, do nothing */
1155     /* problem: level teleport landing escapes the check */
1156     if (!on_level(&u.uz, &u.uz0))
1157         return;
1158
1159 /*JP
1160     You("activated a magic portal!");
1161 */
1162     pline("\96\82\96@\82Ì\93ü\8cû\82ª\8dì\93®\82µ\82½\81I");
1163
1164     /* prevent the poor shnook, whose amulet was stolen while in
1165      * the endgame, from accidently triggering the portal to the
1166      * next level, and thus losing the game
1167      */
1168     if (In_endgame(&u.uz) && !u.uhave.amulet) {
1169 /*JP
1170         You_feel("dizzy for a moment, but nothing happens...");
1171 */
1172         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");
1173         return;
1174     }
1175
1176     target_level = ttmp->dst;
1177     schedule_goto(&target_level, FALSE, FALSE, 1,
1178 /*JP
1179                   "You feel dizzy for a moment, but the sensation passes.",
1180 */
1181                   "\88ê\8fu\82ß\82Ü\82¢\82ð\8a´\82\82½\81C\82µ\82©\82µ\82»\82Ì\8a´\8ao\82Í\8fÁ\82¦\82½\81D",
1182                   (char *) 0);
1183 }
1184
1185 void
1186 tele_trap(trap)
1187 struct trap *trap;
1188 {
1189     if (In_endgame(&u.uz) || Antimagic) {
1190         if (Antimagic)
1191             shieldeff(u.ux, u.uy);
1192 /*JP
1193         You_feel("a wrenching sensation.");
1194 */
1195         You("\82Ë\82\82ç\82ê\82½\82æ\82¤\82È\8a´\8ao\82ð\8a´\82\82½\81D");
1196     } else if (!next_to_u()) {
1197         You1(shudder_for_moment);
1198     } else if (trap->once) {
1199         deltrap(trap);
1200         newsym(u.ux, u.uy); /* get rid of trap symbol */
1201         vault_tele();
1202     } else
1203         tele();
1204 }
1205
1206 void
1207 level_tele_trap(trap, trflags)
1208 struct trap *trap;
1209 unsigned trflags;
1210 {
1211 #if 0 /*JP*/
1212     char verbbuf[BUFSZ];
1213
1214     if ((trflags & VIASITTING) != 0)
1215         Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1216     else
1217         Sprintf(verbbuf, "%s onto",
1218                 Levitation ? (const char *) "float"
1219                            : locomotion(youmonst.data, "step"));
1220     You("%s a level teleport trap!", verbbuf);
1221 #else
1222     if ((trflags & VIASITTING) != 0) {
1223         pline("\95Ê\82Ì\8aK\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82ª\94­\93®\82µ\82½\81I");
1224     } else {
1225         You("\95Ê\82Ì\8aK\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82ð%s\81I",
1226             Levitation ? (const char *) "\8c©\89º\82ë\82µ\82½"
1227                        : jpast(locomotion(youmonst.data, "\93¥\82Þ")));
1228     }
1229 #endif
1230
1231     if (Antimagic) {
1232         shieldeff(u.ux, u.uy);
1233     }
1234     if (Antimagic || In_endgame(&u.uz)) {
1235 /*JP
1236         You_feel("a wrenching sensation.");
1237 */
1238         You("\82Ë\82\82ç\82ê\82½\82æ\82¤\82È\8a´\8ao\82ð\8a´\82\82½\81D");
1239         return;
1240     }
1241     if (!Blind)
1242 /*JP
1243         You("are momentarily blinded by a flash of light.");
1244 */
1245         You("\82Ü\82Î\82ä\82¢\8cõ\82Å\88ê\8fu\96Ú\82ª\82­\82ç\82ñ\82¾\81D");
1246     else
1247 /*JP
1248         You("are momentarily disoriented.");
1249 */
1250         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
1251     deltrap(trap);
1252     newsym(u.ux, u.uy); /* get rid of trap symbol */
1253     level_tele();
1254 }
1255
1256 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1257 STATIC_OVL boolean
1258 rloc_pos_ok(x, y, mtmp)
1259 register int x, y; /* coordinates of candidate location */
1260 struct monst *mtmp;
1261 {
1262     register int xx, yy;
1263
1264     if (!goodpos(x, y, mtmp, 0))
1265         return FALSE;
1266     /*
1267      * Check for restricted areas present in some special levels.
1268      *
1269      * `xx' is current column; if 0, then `yy' will contain flag bits
1270      * rather than row:  bit #0 set => moving upwards; bit #1 set =>
1271      * inside the Wizard's tower.
1272      */
1273     xx = mtmp->mx;
1274     yy = mtmp->my;
1275     if (!xx) {
1276         /* no current location (migrating monster arrival) */
1277         if (dndest.nlx && On_W_tower_level(&u.uz))
1278             return (((yy & 2) != 0)
1279                     /* inside xor not within */
1280                     ^ !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1281                                            dndest.nhx, dndest.nhy));
1282         if (updest.lx && (yy & 1) != 0) /* moving up */
1283             return (within_bounded_area(x, y, updest.lx, updest.ly,
1284                                         updest.hx, updest.hy)
1285                     && (!updest.nlx
1286                         || !within_bounded_area(x, y, updest.nlx, updest.nly,
1287                                                 updest.nhx, updest.nhy)));
1288         if (dndest.lx && (yy & 1) == 0) /* moving down */
1289             return (within_bounded_area(x, y, dndest.lx, dndest.ly,
1290                                         dndest.hx, dndest.hy)
1291                     && (!dndest.nlx
1292                         || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1293                                                 dndest.nhx, dndest.nhy)));
1294     } else {
1295         /* [try to] prevent a shopkeeper or temple priest from being
1296            sent out of his room (caller might resort to goodpos() if
1297            we report failure here, so this isn't full prevention) */
1298         if (mtmp->isshk && inhishop(mtmp)) {
1299             if (levl[x][y].roomno != ESHK(mtmp)->shoproom)
1300                 return FALSE;
1301         } else if (mtmp->ispriest && inhistemple(mtmp)) {
1302             if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1303                 return FALSE;
1304         }
1305         /* current location is <xx,yy> */
1306         if (!tele_jump_ok(xx, yy, x, y))
1307             return FALSE;
1308     }
1309     /* <x,y> is ok */
1310     return TRUE;
1311 }
1312
1313 /*
1314  * rloc_to()
1315  *
1316  * Pulls a monster from its current position and places a monster at
1317  * a new x and y.  If oldx is 0, then the monster was not in the
1318  * levels.monsters array.  However, if oldx is 0, oldy may still have
1319  * a value because mtmp is a migrating_mon.  Worm tails are always
1320  * placed randomly around the head of the worm.
1321  */
1322 void
1323 rloc_to(mtmp, x, y)
1324 struct monst *mtmp;
1325 register int x, y;
1326 {
1327     register int oldx = mtmp->mx, oldy = mtmp->my;
1328     boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1329
1330     if (x == mtmp->mx && y == mtmp->my && m_at(x,y) == mtmp)
1331         return; /* that was easy */
1332
1333     if (oldx) { /* "pick up" monster */
1334         if (mtmp->wormno) {
1335             remove_worm(mtmp);
1336         } else {
1337             remove_monster(oldx, oldy);
1338             newsym(oldx, oldy); /* update old location */
1339         }
1340     }
1341
1342     memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
1343     place_monster(mtmp, x, y); /* put monster down */
1344     update_monster_region(mtmp);
1345
1346     if (mtmp->wormno) /* now put down tail */
1347         place_worm_tail_randomly(mtmp, x, y);
1348
1349     if (u.ustuck == mtmp) {
1350         if (u.uswallow) {
1351             u.ux = x;
1352             u.uy = y;
1353             docrt();
1354         } else
1355             u.ustuck = 0;
1356     }
1357
1358     newsym(x, y);      /* update new location */
1359     set_apparxy(mtmp); /* orient monster */
1360
1361     /* shopkeepers will only teleport if you zap them with a wand of
1362        teleportation or if they've been transformed into a jumpy monster;
1363        the latter only happens if you've attacked them with polymorph */
1364     if (resident_shk && !inhishop(mtmp))
1365         make_angry_shk(mtmp, oldx, oldy);
1366 }
1367
1368 /* place a monster at a random location, typically due to teleport */
1369 /* return TRUE if successful, FALSE if not */
1370 boolean
1371 rloc(mtmp, suppress_impossible)
1372 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1373 boolean suppress_impossible;
1374 {
1375     register int x, y, trycount;
1376
1377     if (mtmp == u.usteed) {
1378         tele();
1379         return TRUE;
1380     }
1381
1382     if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */
1383         if (!In_W_tower(u.ux, u.uy, &u.uz))
1384             x = xupstair, y = yupstair;
1385         else if (!xdnladder) /* bottom level of tower */
1386             x = xupladder, y = yupladder;
1387         else
1388             x = xdnladder, y = ydnladder;
1389         /* if the wiz teleports away to heal, try the up staircase,
1390            to block the player's escaping before he's healed
1391            (deliberately use `goodpos' rather than `rloc_pos_ok' here) */
1392         if (goodpos(x, y, mtmp, 0))
1393             goto found_xy;
1394     }
1395
1396     trycount = 0;
1397     do {
1398         x = rn1(COLNO - 3, 2);
1399         y = rn2(ROWNO);
1400         if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1401                              : goodpos(x, y, mtmp, 0))
1402             goto found_xy;
1403     } while (++trycount < 1000);
1404
1405     /* last ditch attempt to find a good place */
1406     for (x = 2; x < COLNO - 1; x++)
1407         for (y = 0; y < ROWNO; y++)
1408             if (goodpos(x, y, mtmp, 0))
1409                 goto found_xy;
1410
1411     /* level either full of monsters or somehow faulty */
1412     if (!suppress_impossible)
1413         impossible("rloc(): couldn't relocate monster");
1414     return FALSE;
1415
1416 found_xy:
1417     rloc_to(mtmp, x, y);
1418     return TRUE;
1419 }
1420
1421 STATIC_OVL void
1422 mvault_tele(mtmp)
1423 struct monst *mtmp;
1424 {
1425     register struct mkroom *croom = search_special(VAULT);
1426     coord c;
1427
1428     if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1429         rloc_to(mtmp, c.x, c.y);
1430         return;
1431     }
1432     (void) rloc(mtmp, TRUE);
1433 }
1434
1435 boolean
1436 tele_restrict(mon)
1437 struct monst *mon;
1438 {
1439     if (level.flags.noteleport) {
1440         if (canseemon(mon))
1441 #if 0 /*JP*/
1442             pline("A mysterious force prevents %s from teleporting!",
1443                   mon_nam(mon));
1444 #else
1445             pline("\8aï\96­\82È\97Í\82ª%s\82Ì\8fu\8aÔ\88Ú\93®\82ð\96h\82¢\82¾\81I",
1446                   mon_nam(mon));
1447 #endif
1448         return TRUE;
1449     }
1450     return FALSE;
1451 }
1452
1453 void
1454 mtele_trap(mtmp, trap, in_sight)
1455 struct monst *mtmp;
1456 struct trap *trap;
1457 int in_sight;
1458 {
1459     char *monname;
1460
1461     if (tele_restrict(mtmp))
1462         return;
1463     if (teleport_pet(mtmp, FALSE)) {
1464         /* save name with pre-movement visibility */
1465         monname = Monnam(mtmp);
1466
1467         /* Note: don't remove the trap if a vault.  Other-
1468          * wise the monster will be stuck there, since
1469          * the guard isn't going to come for it...
1470          */
1471         if (trap->once)
1472             mvault_tele(mtmp);
1473         else
1474             (void) rloc(mtmp, TRUE);
1475
1476         if (in_sight) {
1477             if (canseemon(mtmp))
1478 /*JP
1479                 pline("%s seems disoriented.", monname);
1480 */
1481                 pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\82æ\82¤\82¾\81D", monname);
1482             else
1483 /*JP
1484                 pline("%s suddenly disappears!", monname);
1485 */
1486                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", monname);
1487             seetrap(trap);
1488         }
1489     }
1490 }
1491
1492 /* return 0 if still on level, 3 if not */
1493 int
1494 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1495 struct monst *mtmp;
1496 struct trap *trap;
1497 boolean force_it;
1498 int in_sight;
1499 {
1500     int tt = (trap ? trap->ttyp : NO_TRAP);
1501
1502     if (mtmp == u.ustuck) /* probably a vortex */
1503         return 0;         /* temporary? kludge */
1504     if (teleport_pet(mtmp, force_it)) {
1505         d_level tolevel;
1506         int migrate_typ = MIGR_RANDOM;
1507
1508         if (is_hole(tt)) {
1509             if (Is_stronghold(&u.uz)) {
1510                 assign_level(&tolevel, &valley_level);
1511             } else if (Is_botlevel(&u.uz)) {
1512                 if (in_sight && trap->tseen)
1513 #if 0 /*JP*/
1514                     pline("%s avoids the %s.", Monnam(mtmp),
1515                           (tt == HOLE) ? "hole" : "trap");
1516 #else
1517                     pline("%s\82Í%s\82ð\89ñ\94ð\82µ\82½\81D", Monnam(mtmp),
1518                           (tt == HOLE) ? "\8c\8a" : "ã©");
1519 #endif
1520                 return 0;
1521             } else {
1522                 get_level(&tolevel, depth(&u.uz) + 1);
1523             }
1524         } else if (tt == MAGIC_PORTAL) {
1525             if (In_endgame(&u.uz)
1526                 && (mon_has_amulet(mtmp) || is_home_elemental(mtmp->data))) {
1527                 if (in_sight && mtmp->data->mlet != S_ELEMENTAL) {
1528 /*JP
1529                     pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1530 */
1531                     pline("%s\82ª\88ê\8fu\8bP\82¢\82½\82æ\82¤\82É\8c©\82¦\82½\81D", Monnam(mtmp));
1532                     seetrap(trap);
1533                 }
1534                 return 0;
1535             } else {
1536                 assign_level(&tolevel, &trap->dst);
1537                 migrate_typ = MIGR_PORTAL;
1538             }
1539         } else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
1540             int nlev;
1541
1542             if (mon_has_amulet(mtmp) || In_endgame(&u.uz)
1543                 /* NO_TRAP is used when forcing a monster off the level;
1544                    onscary(0,0,) is true for the Wizard, Riders, lawful
1545                    minions, Angels of any alignment, shopkeeper or priest
1546                    currently inside his or her own special room */
1547                 || (tt == NO_TRAP && onscary(0, 0, mtmp))) {
1548                 if (in_sight)
1549 /*JP
1550                     pline("%s seems very disoriented for a moment.",
1551 */
1552                     pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82¾\81D",
1553                           Monnam(mtmp));
1554                 return 0;
1555             }
1556             if (tt == NO_TRAP) {
1557                 /* creature is being forced off the level to make room;
1558                    it will try to return to this level (at a random spot
1559                    rather than its current one) if the level is left by
1560                    the hero and then revisited */
1561                 assign_level(&tolevel, &u.uz);
1562             } else {
1563                 nlev = random_teleport_level();
1564                 if (nlev == depth(&u.uz)) {
1565                     if (in_sight)
1566 /*JP
1567                     pline("%s shudders for a moment.", Monnam(mtmp));
1568 */
1569                     pline("%s\82Í\88ê\8fu\90k\82¦\82½\81D", Monnam(mtmp));
1570                     return 0;
1571                 }
1572                 get_level(&tolevel, nlev);
1573             }
1574         } else {
1575             impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
1576             return 0;
1577         }
1578
1579         if (in_sight) {
1580 /*JP
1581             pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1582 */
1583             pline("\93Ë\91R%s\82ª\8e\8b\8aE\82©\82ç\8fÁ\82¦\82½\81D", mon_nam(mtmp));
1584             if (trap)
1585                 seetrap(trap);
1586         }
1587         migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1588         return 3; /* no longer on this level */
1589     }
1590     return 0;
1591 }
1592
1593 /* place object randomly, returns False if it's gone (eg broken) */
1594 boolean
1595 rloco(obj)
1596 register struct obj *obj;
1597 {
1598     register xchar tx, ty, otx, oty;
1599     boolean restricted_fall;
1600     int try_limit = 4000;
1601
1602     if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1603         if (revive_corpse(obj))
1604             return FALSE;
1605     }
1606
1607     obj_extract_self(obj);
1608     otx = obj->ox;
1609     oty = obj->oy;
1610     restricted_fall = (otx == 0 && dndest.lx);
1611     do {
1612         tx = rn1(COLNO - 3, 2);
1613         ty = rn2(ROWNO);
1614         if (!--try_limit)
1615             break;
1616     } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1617              || (restricted_fall
1618                  && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1619                                           dndest.hx, dndest.hy)
1620                      || (dndest.nlx
1621                          && within_bounded_area(tx, ty,
1622                                                 dndest.nlx, dndest.nly,
1623                                                 dndest.nhx, dndest.nhy))))
1624              /* on the Wizard Tower levels, objects inside should
1625                 stay inside and objects outside should stay outside */
1626              || (dndest.nlx && On_W_tower_level(&u.uz)
1627                  && within_bounded_area(tx, ty, dndest.nlx, dndest.nly,
1628                                         dndest.nhx, dndest.nhy)
1629                     != within_bounded_area(otx, oty, dndest.nlx, dndest.nly,
1630                                            dndest.nhx, dndest.nhy)));
1631
1632 /*JP
1633     if (flooreffects(obj, tx, ty, "fall")) {
1634 */
1635     if (flooreffects(obj, tx, ty, "\97\8e\82¿\82é")) {
1636         return FALSE;
1637     } else if (otx == 0 && oty == 0) {
1638         ; /* fell through a trap door; no update of old loc needed */
1639     } else {
1640         if (costly_spot(otx, oty)
1641             && (!costly_spot(tx, ty)
1642                 || !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) {
1643             if (costly_spot(u.ux, u.uy)
1644                 && index(u.urooms, *in_rooms(otx, oty, 0)))
1645                 addtobill(obj, FALSE, FALSE, FALSE);
1646             else
1647                 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1648         }
1649         newsym(otx, oty); /* update old location */
1650     }
1651     place_object(obj, tx, ty);
1652     newsym(tx, ty);
1653     return TRUE;
1654 }
1655
1656 /* Returns an absolute depth */
1657 int
1658 random_teleport_level()
1659 {
1660     int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1661
1662     /* [the endgame case can only occur in wizard mode] */
1663     if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1664         return cur_depth;
1665
1666     /* What I really want to do is as follows:
1667      * -- If in a dungeon that goes down, the new level is to be restricted
1668      *    to [top of parent, bottom of current dungeon]
1669      * -- If in a dungeon that goes up, the new level is to be restricted
1670      *    to [top of current dungeon, bottom of parent]
1671      * -- If in a quest dungeon or similar dungeon entered by portals,
1672      *    the new level is to be restricted to [top of current dungeon,
1673      *    bottom of current dungeon]
1674      * The current behavior is not as sophisticated as that ideal, but is
1675      * still better what we used to do, which was like this for players
1676      * but different for monsters for no obvious reason.  Currently, we
1677      * must explicitly check for special dungeons.  We check for Knox
1678      * above; endgame is handled in the caller due to its different
1679      * message ("disoriented").
1680      * --KAA
1681      * 3.4.2: explicitly handle quest here too, to fix the problem of
1682      * monsters sometimes level teleporting out of it into main dungeon.
1683      * Also prevent monsters reaching the Sanctum prior to invocation.
1684      */
1685     if (In_quest(&u.uz)) {
1686         int bottom = dunlevs_in_dungeon(&u.uz),
1687             qlocate_depth = qlocate_level.dlevel;
1688
1689         /* if hero hasn't reached the middle locate level yet,
1690            no one can randomly teleport past it */
1691         if (dunlev_reached(&u.uz) < qlocate_depth)
1692             bottom = qlocate_depth;
1693         min_depth = dungeons[u.uz.dnum].depth_start;
1694         max_depth = bottom + (dungeons[u.uz.dnum].depth_start - 1);
1695     } else {
1696         min_depth = 1;
1697         max_depth =
1698             dunlevs_in_dungeon(&u.uz) + (dungeons[u.uz.dnum].depth_start - 1);
1699         /* can't reach Sanctum if the invocation hasn't been performed */
1700         if (Inhell && !u.uevent.invoked)
1701             max_depth -= 1;
1702     }
1703
1704     /* Get a random value relative to the current dungeon */
1705     /* Range is 1 to current+3, current not counting */
1706     nlev = rn2(cur_depth + 3 - min_depth) + min_depth;
1707     if (nlev >= cur_depth)
1708         nlev++;
1709
1710     if (nlev > max_depth) {
1711         nlev = max_depth;
1712         /* teleport up if already on bottom */
1713         if (Is_botlevel(&u.uz))
1714             nlev -= rnd(3);
1715     }
1716     if (nlev < min_depth) {
1717         nlev = min_depth;
1718         if (nlev == cur_depth) {
1719             nlev += rnd(3);
1720             if (nlev > max_depth)
1721                 nlev = max_depth;
1722         }
1723     }
1724     return nlev;
1725 }
1726
1727 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1728    return false iff the attempt fails */
1729 boolean
1730 u_teleport_mon(mtmp, give_feedback)
1731 struct monst *mtmp;
1732 boolean give_feedback;
1733 {
1734     coord cc;
1735
1736     if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1737         if (give_feedback)
1738 /*JP
1739             pline("%s resists your magic!", Monnam(mtmp));
1740 */
1741             pline("%s\82Í\96\82\96@\82ð\96h\82¢\82¾\81I", Monnam(mtmp));
1742         return FALSE;
1743     } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1744         if (give_feedback)
1745 /*JP
1746             You("are no longer inside %s!", mon_nam(mtmp));
1747 */
1748             You("%s\82Ì\93à\95\94\82©\82ç\92E\8fo\82µ\82½\81I", mon_nam(mtmp));
1749         unstuck(mtmp);
1750         (void) rloc(mtmp, TRUE);
1751     } else if (is_rider(mtmp->data) && rn2(13)
1752                && enexto(&cc, u.ux, u.uy, mtmp->data))
1753         rloc_to(mtmp, cc.x, cc.y);
1754     else
1755         (void) rloc(mtmp, TRUE);
1756     return TRUE;
1757 }
1758
1759 /*teleport.c*/