OSDN Git Service

update year to 2020
[jnethack/source.git] / src / teleport.c
1 /* NetHack 3.6  teleport.c      $NHDT-Date: 1576281515 2019/12/13 23:58:35 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.95 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
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 (x == u.ux && y == u.uy
48         && mtmp != &youmonst && (mtmp != u.ustuck || !u.uswallow)
49         && (!u.usteed || mtmp != u.usteed))
50         return FALSE;
51
52     if (mtmp) {
53         struct monst *mtmp2 = m_at(x, y);
54
55         /* Be careful with long worms.  A monster may be placed back in
56          * its own location.  Normally, if m_at() returns the same monster
57          * that we're trying to place, the monster is being placed in its
58          * own location.  However, that is not correct for worm segments,
59          * because all the segments of the worm return the same m_at().
60          * Actually we overdo the check a little bit--a worm can't be placed
61          * in its own location, period.  If we just checked for mtmp->mx
62          * != x || mtmp->my != y, we'd miss the case where we're called
63          * to place the worm segment and the worm's head is at x,y.
64          */
65         if (mtmp2 && (mtmp2 != mtmp || mtmp->wormno))
66             return FALSE;
67
68         mdat = mtmp->data;
69         if (is_pool(x, y) && !ignorewater) {
70             /* [what about Breathless?] */
71             if (mtmp == &youmonst)
72                 return (Swimming || Amphibious
73                         || (!Is_waterlevel(&u.uz)
74                             /* water on the Plane of Water has no surface
75                                so there's no way to be on or above that */
76                             && (Levitation || Flying || Wwalking)));
77             else
78                 return (is_swimmer(mdat)
79                         || (!Is_waterlevel(&u.uz)
80                             && (is_floater(mdat) || is_flyer(mdat)
81                                 || is_clinger(mdat))));
82         } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
83             return FALSE;
84         } else if (is_lava(x, y)) {
85             /* 3.6.3: floating eye can levitate over lava but it avoids
86                that due the effect of the heat causing it to dry out */
87             if (mdat == &mons[PM_FLOATING_EYE])
88                 return FALSE;
89             else if (mtmp == &youmonst)
90                 return (Levitation || Flying
91                         || (Fire_resistance && Wwalking && uarmf
92                             && uarmf->oerodeproof)
93                         || (Upolyd && likes_lava(youmonst.data)));
94             else
95                 return (is_floater(mdat) || is_flyer(mdat)
96                         || likes_lava(mdat));
97         }
98         if (passes_walls(mdat) && may_passwall(x, y))
99             return TRUE;
100         if (amorphous(mdat) && closed_door(x, y))
101             return TRUE;
102     }
103     if (!accessible(x, y)) {
104         if (!(is_pool(x, y) && ignorewater))
105             return FALSE;
106     }
107
108     if (sobj_at(BOULDER, x, y) && (!mdat || !throws_rocks(mdat)))
109         return FALSE;
110     return TRUE;
111 }
112
113 /*
114  * "entity next to"
115  *
116  * Attempt to find a good place for the given monster type in the closest
117  * position to (xx,yy).  Do so in successive square rings around (xx,yy).
118  * If there is more than one valid position in the ring, choose one randomly.
119  * Return TRUE and the position chosen when successful, FALSE otherwise.
120  */
121 boolean
122 enexto(cc, xx, yy, mdat)
123 coord *cc;
124 register xchar xx, yy;
125 struct permonst *mdat;
126 {
127     return enexto_core(cc, xx, yy, mdat, NO_MM_FLAGS);
128 }
129
130 boolean
131 enexto_core(cc, xx, yy, mdat, entflags)
132 coord *cc;
133 xchar xx, yy;
134 struct permonst *mdat;
135 unsigned entflags;
136 {
137 #define MAX_GOOD 15
138     coord good[MAX_GOOD], *good_ptr;
139     int x, y, range, i;
140     int xmin, xmax, ymin, ymax, rangemax;
141     struct monst fakemon; /* dummy monster */
142     boolean allow_xx_yy = (boolean) ((entflags & GP_ALLOW_XY) != 0);
143
144     entflags &= ~GP_ALLOW_XY;
145     if (!mdat) {
146         debugpline0("enexto() called with null mdat");
147         /* default to player's original monster type */
148         mdat = &mons[u.umonster];
149     }
150     fakemon = zeromonst;
151     set_mon_data(&fakemon, mdat); /* set up for goodpos */
152
153     /* used to use 'if (range > ROWNO && range > COLNO) return FALSE' below,
154        so effectively 'max(ROWNO, COLNO)' which performs useless iterations
155        (possibly many iterations if <xx,yy> is in the center of the map) */
156     xmax = max(xx - 1, (COLNO - 1) - xx);
157     ymax = max(yy - 0, (ROWNO - 1) - yy);
158     rangemax = max(xmax, ymax);
159     /* setup: no suitable spots yet, first iteration checks adjacent spots */
160     good_ptr = good;
161     range = 1;
162     /*
163      * Walk around the border of the square with center (xx,yy) and
164      * radius range.  Stop when we find at least one valid position.
165      */
166     do {
167         xmin = max(1, xx - range);
168         xmax = min(COLNO - 1, xx + range);
169         ymin = max(0, yy - range);
170         ymax = min(ROWNO - 1, yy + range);
171
172         for (x = xmin; x <= xmax; x++) {
173             if (goodpos(x, ymin, &fakemon, entflags)) {
174                 good_ptr->x = x;
175                 good_ptr->y = ymin;
176                 /* beware of accessing beyond segment boundaries.. */
177                 if (good_ptr++ == &good[MAX_GOOD - 1])
178                     goto full;
179             }
180             if (goodpos(x, ymax, &fakemon, entflags)) {
181                 good_ptr->x = x;
182                 good_ptr->y = ymax;
183                 if (good_ptr++ == &good[MAX_GOOD - 1])
184                     goto full;
185             }
186         }
187         /* 3.6.3: this used to use 'ymin+1' which left top row unchecked */
188         for (y = ymin; y < ymax; y++) {
189             if (goodpos(xmin, y, &fakemon, entflags)) {
190                 good_ptr->x = xmin;
191                 good_ptr->y = y;
192                 if (good_ptr++ == &good[MAX_GOOD - 1])
193                     goto full;
194             }
195             if (goodpos(xmax, y, &fakemon, entflags)) {
196                 good_ptr->x = xmax;
197                 good_ptr->y = y;
198                 if (good_ptr++ == &good[MAX_GOOD - 1])
199                     goto full;
200             }
201         }
202     } while (++range <= rangemax && good_ptr == good);
203
204     /* return False if we exhausted 'range' without finding anything */
205     if (good_ptr == good) {
206         /* 3.6.3: earlier versions didn't have the option to try <xx,yy>,
207            and left 'cc' uninitialized when returning False */
208         cc->x = xx, cc->y = yy;
209         /* if every spot other than <xx,yy> has failed, try <xx,yy> itself */
210         if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) {
211             return TRUE; /* 'cc' is set */
212         } else {
213             debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy);
214             return FALSE;
215         }
216     }
217
218  full:
219     /* we've got between 1 and SIZE(good) candidates; choose one */
220     i = rn2((int) (good_ptr - good));
221     cc->x = good[i].x;
222     cc->y = good[i].y;
223     return TRUE;
224 }
225
226 /*
227  * Check for restricted areas present in some special levels.  (This might
228  * need to be augmented to allow deliberate passage in wizard mode, but
229  * only for explicitly chosen destinations.)
230  */
231 STATIC_OVL boolean
232 tele_jump_ok(x1, y1, x2, y2)
233 int x1, y1, x2, y2;
234 {
235     if (!isok(x2, y2))
236         return FALSE;
237     if (dndest.nlx > 0) {
238         /* if inside a restricted region, can't teleport outside */
239         if (within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
240                                 dndest.nhy)
241             && !within_bounded_area(x2, y2, dndest.nlx, dndest.nly,
242                                     dndest.nhx, dndest.nhy))
243             return FALSE;
244         /* and if outside, can't teleport inside */
245         if (!within_bounded_area(x1, y1, dndest.nlx, dndest.nly, dndest.nhx,
246                                  dndest.nhy)
247             && within_bounded_area(x2, y2, dndest.nlx, dndest.nly, dndest.nhx,
248                                    dndest.nhy))
249             return FALSE;
250     }
251     if (updest.nlx > 0) { /* ditto */
252         if (within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
253                                 updest.nhy)
254             && !within_bounded_area(x2, y2, updest.nlx, updest.nly,
255                                     updest.nhx, updest.nhy))
256             return FALSE;
257         if (!within_bounded_area(x1, y1, updest.nlx, updest.nly, updest.nhx,
258                                  updest.nhy)
259             && within_bounded_area(x2, y2, updest.nlx, updest.nly, updest.nhx,
260                                    updest.nhy))
261             return FALSE;
262     }
263     return TRUE;
264 }
265
266 STATIC_OVL boolean
267 teleok(x, y, trapok)
268 register int x, y;
269 boolean trapok;
270 {
271     if (!trapok) {
272         /* allow teleportation onto vibrating square, it's not a real trap */
273         struct trap *trap = t_at(x, y);
274
275         if (trap && trap->ttyp != VIBRATING_SQUARE)
276             return FALSE;
277     }
278     if (!goodpos(x, y, &youmonst, 0))
279         return FALSE;
280     if (!tele_jump_ok(u.ux, u.uy, x, y))
281         return FALSE;
282     if (!in_out_region(x, y))
283         return FALSE;
284     return TRUE;
285 }
286
287 void
288 teleds(nux, nuy, allow_drag)
289 register int nux, nuy;
290 boolean allow_drag;
291 {
292     boolean ball_active, ball_still_in_range;
293     struct monst *vault_guard = vault_occupied(u.urooms) ? findgd() : 0;
294
295     if (u.utraptype == TT_BURIEDBALL) {
296         /* unearth it */
297         buried_ball_to_punishment();
298     }
299     ball_active = (Punished && uball->where != OBJ_FREE);
300     ball_still_in_range = FALSE;
301
302     /* If they have to move the ball, then drag if allow_drag is true;
303      * otherwise they are teleporting, so unplacebc().
304      * If they don't have to move the ball, then always "drag" whether or
305      * not allow_drag is true, because we are calling that function, not
306      * to drag, but to move the chain.  *However* there are some dumb
307      * special cases:
308      *    0                          0
309      *   _X  move east       ----->  X_
310      *    @                           @
311      * These are permissible if teleporting, but not if dragging.  As a
312      * result, drag_ball() needs to know about allow_drag and might end
313      * up dragging the ball anyway.  Also, drag_ball() might find that
314      * dragging the ball is completely impossible (ball in range but there's
315      * rock in the way), in which case it teleports the ball on its own.
316      */
317     if (ball_active) {
318         if (!carried(uball) && distmin(nux, nuy, uball->ox, uball->oy) <= 2) {
319             ball_still_in_range = TRUE; /* don't have to move the ball */
320         } else {
321             /* have to move the ball */
322             if (!allow_drag || distmin(u.ux, u.uy, nux, nuy) > 1) {
323                 /* we should not have dist > 1 and allow_drag at the same
324                  * time, but just in case, we must then revert to teleport.
325                  */
326                 allow_drag = FALSE;
327                 unplacebc();
328             }
329         }
330     }
331     reset_utrap(FALSE);
332     u.ustuck = 0;
333     u.ux0 = u.ux;
334     u.uy0 = u.uy;
335
336     if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
337         /* mimics stop being unnoticed */
338         youmonst.m_ap_type = M_AP_NOTHING;
339     }
340
341     if (u.uswallow) {
342         u.uswldtim = u.uswallow = 0;
343         if (Punished && !ball_active) {
344             /* ensure ball placement, like unstuck */
345             ball_active = TRUE;
346             allow_drag = FALSE;
347         }
348         docrt();
349     }
350     if (ball_active) {
351         if (ball_still_in_range || allow_drag) {
352             int bc_control;
353             xchar ballx, bally, chainx, chainy;
354             boolean cause_delay;
355
356             if (drag_ball(nux, nuy, &bc_control, &ballx, &bally, &chainx,
357                           &chainy, &cause_delay, allow_drag)) {
358                 move_bc(0, bc_control, ballx, bally, chainx, chainy);
359             } else {
360                 /* dragging fails if hero is encumbered beyond 'burdened' */
361                 allow_drag = FALSE; /* teleport b&c to hero's new spot */
362                 unplacebc(); /* to match placebc() below */
363             }
364         }
365     }
366     /* must set u.ux, u.uy after drag_ball(), which may need to know
367        the old position if allow_drag is true... */
368     u_on_newpos(nux, nuy); /* set u.<x,y>, usteed-><mx,my>; cliparound() */
369     fill_pit(u.ux0, u.uy0);
370     if (ball_active) {
371         if (!ball_still_in_range && !allow_drag)
372             placebc();
373     }
374     initrack(); /* teleports mess up tracking monsters without this */
375     update_player_regions();
376     /*
377      *  Make sure the hero disappears from the old location.  This will
378      *  not happen if she is teleported within sight of her previous
379      *  location.  Force a full vision recalculation because the hero
380      *  is now in a new location.
381      */
382     newsym(u.ux0, u.uy0);
383     see_monsters();
384     vision_full_recalc = 1;
385     nomul(0);
386     vision_recalc(0); /* vision before effects */
387     /* if terrain type changes, levitation or flying might become blocked
388        or unblocked; might issue message, so do this after map+vision has
389        been updated for new location instead of right after u_on_newpos() */
390     if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ)
391         switch_terrain();
392     if (telescroll) {
393         /* when teleporting by scroll, we need to handle discovery
394            now before getting feedback about any objects at our
395            destination since we might land on another such scroll */
396         if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0))
397             learnscroll(telescroll);
398         else
399             telescroll = 0; /* no discovery by scrolltele()'s caller */
400     }
401     /* sequencing issue:  we want guard's alarm, if any, to occur before
402        room entry message, if any, so need to check for vault exit prior
403        to spoteffects; but spoteffects() sets up new value for u.urooms
404        and vault code depends upon that value, so we need to fake it */
405     if (vault_guard) {
406         char save_urooms[5]; /* [sizeof u.urooms] */
407
408         Strcpy(save_urooms, u.urooms);
409         Strcpy(u.urooms, in_rooms(u.ux, u.uy, VAULT));
410         /* if hero has left vault, make guard notice */
411         if (!vault_occupied(u.urooms))
412             uleftvault(vault_guard);
413         Strcpy(u.urooms, save_urooms); /* reset prior to spoteffects() */
414     }
415     /* possible shop entry message comes after guard's shrill whistle */
416     spoteffects(TRUE);
417     invocation_message();
418 }
419
420 boolean
421 safe_teleds(allow_drag)
422 boolean allow_drag;
423 {
424     register int nux, nuy, tcnt = 0;
425
426     do {
427         nux = rnd(COLNO - 1);
428         nuy = rn2(ROWNO);
429     } while (!teleok(nux, nuy, (boolean) (tcnt > 200)) && ++tcnt <= 400);
430
431     if (tcnt <= 400) {
432         teleds(nux, nuy, allow_drag);
433         return TRUE;
434     } else
435         return FALSE;
436 }
437
438 STATIC_OVL void
439 vault_tele()
440 {
441     register struct mkroom *croom = search_special(VAULT);
442     coord c;
443
444     if (croom && somexy(croom, &c) && teleok(c.x, c.y, FALSE)) {
445         teleds(c.x, c.y, FALSE);
446         return;
447     }
448     tele();
449 }
450
451 boolean
452 teleport_pet(mtmp, force_it)
453 register struct monst *mtmp;
454 boolean force_it;
455 {
456     register struct obj *otmp;
457
458     if (mtmp == u.usteed)
459         return FALSE;
460
461     if (mtmp->mleashed) {
462         otmp = get_mleash(mtmp);
463         if (!otmp) {
464             impossible("%s is leashed, without a leash.", Monnam(mtmp));
465             goto release_it;
466         }
467         if (otmp->cursed && !force_it) {
468             yelp(mtmp);
469             return FALSE;
470         } else {
471 /*JP
472             Your("leash goes slack.");
473 */
474             Your("\95R\82Í\82½\82é\82ñ\82¾\81D");
475  release_it:
476             m_unleash(mtmp, FALSE);
477             return TRUE;
478         }
479     }
480     return TRUE;
481 }
482
483 /* teleport the hero via some method other than scroll of teleport */
484 void
485 tele()
486 {
487     (void) scrolltele((struct obj *) 0);
488 }
489
490 /* teleport the hero; return true if scroll of teleportation should become
491    discovered; teleds() will usually do the actual discovery, since the
492    outcome sometimes depends upon destination and discovery needs to be
493    performed before arrival, in case we land on another teleport scroll */
494 boolean
495 scrolltele(scroll)
496 struct obj *scroll;
497 {
498     coord cc;
499     boolean result = FALSE; /* don't learn scroll */
500
501     /* Disable teleportation in stronghold && Vlad's Tower */
502     if (level.flags.noteleport) {
503         if (!wizard) {
504 /*JP
505             pline("A mysterious force prevents you from teleporting!");
506 */
507             pline("\8aï\96­\82È\97Í\82ª\8fu\8aÔ\88Ú\93®\82ð\96h\82¢\82¾\81I");
508             return TRUE;
509         }
510     }
511
512     /* don't show trap if "Sorry..." */
513     if (!Blinded)
514         make_blinded(0L, FALSE);
515
516     if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
517 /*JP
518         You_feel("disoriented for a moment.");
519 */
520         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
521         if (!wizard || yn("Override?") != 'y')
522             return FALSE;
523     }
524     if ((Teleport_control && !Stunned) || wizard) {
525         if (unconscious()) {
526 /*JP
527             pline("Being unconscious, you cannot control your teleport.");
528 */
529             pline("\88Ó\8e¯\82ª\82È\82¢\82Ì\82Å\81C\82 \82È\82½\82Í\8fu\8aÔ\88Ú\93®\82ð\90§\8cä\82Å\82«\82È\82¢\81D");
530         } else {
531 #if 0 /*JP*//*\8eå\8cê\82ð\8fÈ\97ª\82µ\82Ä\8aÈ\97ª\89»*/
532             char whobuf[BUFSZ];
533
534             Strcpy(whobuf, "you");
535             if (u.usteed)
536                 Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
537             pline("Where do %s want to be teleported?", whobuf);
538 #else
539             pline("\82Ç\82Ì\88Ê\92u\82É\8fu\8aÔ\88Ú\93®\82µ\82Ü\82·\82©\81H");
540 #endif
541             cc.x = u.ux;
542             cc.y = u.uy;
543 /*JP
544             if (getpos(&cc, TRUE, "the desired position") < 0)
545 */
546             if (getpos(&cc, TRUE, "\88Ú\93®\82µ\82½\82¢\8fê\8f\8a") < 0)
547                 return TRUE; /* abort */
548             /* possible extensions: introduce a small error if
549                magic power is low; allow transfer to solid rock */
550             if (teleok(cc.x, cc.y, FALSE)) {
551                 /* for scroll, discover it regardless of destination */
552                 if (scroll)
553                     learnscroll(scroll);
554                 teleds(cc.x, cc.y, FALSE);
555                 return TRUE;
556             }
557 /*JP
558             pline("Sorry...");
559 */
560             pline("\82¨\82Á\82Æ\81D\81D\81D");
561             result = TRUE;
562         }
563     } else if (scroll && scroll->blessed) {
564         /* (this used to be handled in seffects()) */
565 /*JP
566         if (yn("Do you wish to teleport?") == 'n')
567 */
568         if (yn("\8fu\8aÔ\88Ú\93®\82µ\82Ü\82·\82©\81H") == 'n')
569             return TRUE;
570         result = TRUE;
571     }
572
573     telescroll = scroll;
574     (void) safe_teleds(FALSE);
575     /* teleds() will leave telescroll intact iff random destination
576        is far enough away for scroll discovery to be warranted */
577     if (telescroll)
578         result = TRUE;
579     telescroll = 0; /* reset */
580     return result;
581 }
582
583 /* ^T command; 'm ^T' == choose among several teleport modes */
584 int
585 dotelecmd()
586 {
587     long save_HTele, save_ETele;
588     int res, added, hidden;
589     boolean ignore_restrictions = FALSE;
590 /* also defined in spell.c */
591 #define NOOP_SPELL  0
592 #define HIDE_SPELL  1
593 #define ADD_SPELL   2
594 #define UNHIDESPELL 3
595 #define REMOVESPELL 4
596
597     /* normal mode; ignore 'm' prefix if it was given */
598     if (!wizard)
599         return dotele(FALSE);
600
601     added = hidden = NOOP_SPELL;
602     save_HTele = HTeleportation, save_ETele = ETeleportation;
603     if (!iflags.menu_requested) {
604         ignore_restrictions = TRUE;
605     } else {
606         static const struct tporttypes {
607             char menulet;
608             const char *menudesc;
609         } tports[] = {
610             /*
611              * Potential combinations:
612              *  1) attempt ^T without intrinsic, not know spell;
613              *  2) via intrinsic, not know spell, obey restrictions;
614              *  3) via intrinsic, not know spell, ignore restrictions;
615              *  4) via intrinsic, know spell, obey restrictions;
616              *  5) via intrinsic, know spell, ignore restrictions;
617              *  6) via spell, not have intrinsic, obey restrictions;
618              *  7) via spell, not have intrinsic, ignore restrictions;
619              *  8) force, obey other restrictions;
620              *  9) force, ignore restrictions.
621              * We only support the 1st (t), 2nd (n), 6th (s), and 9th (w).
622              *
623              * This ignores the fact that there is an experience level
624              * (or poly-form) requirement which might make normal ^T fail.
625              */
626             { 'n', "normal ^T on demand; no spell, obey restrictions" },
627             { 's', "via spellcast; no intrinsic teleport" },
628             { 't', "try ^T without having it; no spell" },
629             { 'w', "debug mode; ignore restrictions" }, /* trad wizard mode */
630         };
631         menu_item *picks = (menu_item *) 0;
632         anything any;
633         winid win;
634         int i, tmode;
635
636         win = create_nhwindow(NHW_MENU);
637         start_menu(win);
638         any = zeroany;
639         for (i = 0; i < SIZE(tports); ++i) {
640             any.a_int = (int) tports[i].menulet;
641             add_menu(win, NO_GLYPH, &any, (char) any.a_int, 0, ATR_NONE,
642                      tports[i].menudesc,
643                      (tports[i].menulet == 'w') ? MENU_SELECTED
644                                                 : MENU_UNSELECTED);
645         }
646         end_menu(win, "Which way do you want to teleport?");
647         i = select_menu(win, PICK_ONE, &picks);
648         destroy_nhwindow(win);
649         if (i > 0) {
650             tmode = picks[0].item.a_int;
651             /* if we got 2, use the one which wasn't preselected */
652             if (i > 1 && tmode == 'w')
653                 tmode = picks[1].item.a_int;
654             free((genericptr_t) picks);
655         } else if (i == 0) {
656             /* preselected one was explicitly chosen and got toggled off */
657             tmode = 'w';
658         } else { /* ESC */
659             return 0;
660         }
661         switch (tmode) {
662         case 'n':
663             HTeleportation |= I_SPECIAL; /* confer intrinsic teleportation */
664             hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
665             break;
666         case 's':
667             HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
668             added = tport_spell(ADD_SPELL); /* add teleport-away */
669             break;
670         case 't':
671             HTeleportation = ETeleportation = 0L; /* suppress intrinsic */
672             hidden = tport_spell(HIDE_SPELL); /* hide teleport-away */
673             break;
674         case 'w':
675             ignore_restrictions = TRUE;
676             break;
677         }
678     }
679
680     /* if dotele() can be fatal, final disclosure might lie about
681        intrinsic teleportation; we should be able to live with that
682        since the menu finagling is only applicable in wizard mode */
683     res = dotele(ignore_restrictions);
684
685     HTeleportation = save_HTele;
686     ETeleportation = save_ETele;
687     if (added != NOOP_SPELL || hidden != NOOP_SPELL)
688         /* can't both be non-NOOP so addition will yield the non-NOOP one */
689         (void) tport_spell(added + hidden - NOOP_SPELL);
690
691     return res;
692 }
693
694 int
695 dotele(break_the_rules)
696 boolean break_the_rules; /* True: wizard mode ^T */
697 {
698     struct trap *trap;
699     const char *cantdoit;
700     boolean trap_once = FALSE;
701
702     trap = t_at(u.ux, u.uy);
703     if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
704         trap = 0;
705
706     if (trap) {
707         trap_once = trap->once; /* trap may get deleted, save this */
708         if (trap->once) {
709 /*JP
710             pline("This is a vault teleport, usable once only.");
711 */
712             pline("\88ê\93x\82©\82¬\82è\82Ì\91q\8cÉ\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82¾\81D");
713 /*JP
714             if (yn("Jump in?") == 'n') {
715 */
716             if (yn("\94ò\82Ñ\8d\9e\82Þ\81H") == 'n') {
717                 trap = 0;
718             } else {
719                 deltrap(trap);
720                 newsym(u.ux, u.uy);
721             }
722         }
723         if (trap)
724 #if 0 /*JP:T*/
725             You("%s onto the teleportation trap.",
726                 locomotion(youmonst.data, "jump"));
727 #else
728             You("\8fu\8aÔ\88Ú\93®\82Ìã©\82É\94ò\82Ñ\82±\82ñ\82¾\81D");
729 #endif
730     }
731     if (!trap) {
732         boolean castit = FALSE;
733         register int sp_no = 0, energy = 0;
734
735         if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
736                                && !can_teleport(youmonst.data))) {
737             /* Try to use teleport away spell.
738                Prior to 3.6.2 this used to require that you know the spellbook
739                (probably just intended as an optimization to skip the
740                lookup loop) but it is possible to know and cast a spell
741                after forgetting its book due to amnesia. */
742             for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
743                 if (spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY)
744                     break;
745             /* casting isn't inhibited by being Stunned (...it ought to be) */
746             castit = (sp_no < MAXSPELL && !Confusion);
747             if (!castit && !break_the_rules) {
748 #if 0 /*JP:T*/
749                 You("%s.",
750                     !Teleportation ? ((sp_no < MAXSPELL)
751                                         ? "can't cast that spell"
752                                         : "don't know that spell")
753                                    : "are not able to teleport at will");
754 #else
755                 You("%s\81D",
756                     !Teleportation ? ((sp_no < MAXSPELL)
757                                         ? "\82»\82Ì\96\82\96@\82Í\8f¥\82¦\82ç\82ê\82È\82¢"
758                                         : "\82»\82ñ\82È\96\82\96@\82Í\92m\82ç\82È\82¢")
759                                    : "\8e©\95ª\82Ì\88Ó\8ev\82Å\8fu\8aÔ\88Ú\93®\82Å\82«\82È\82¢");
760 #endif
761                 return 0;
762             }
763         }
764
765         cantdoit = 0;
766         /* 3.6.2: the magic numbers for hunger, strength, and energy
767            have been changed to match the ones used in spelleffects().
768            Also, failing these tests used to return 1 and use a move
769            even though casting failure due to these reasons doesn't.
770            [Note: this spellev() is different from the one in spell.c
771            but they both yield the same result.] */
772 #define spellev(spell_otyp) ((int) objects[spell_otyp].oc_level)
773         energy = 5 * spellev(SPE_TELEPORT_AWAY);
774         if (break_the_rules) {
775             if (!castit)
776                 energy = 0;
777             /* spell will cost more if carrying the Amulet, but the
778                amount is rnd(2 * energy) so we can't know by how much;
779                average is twice the normal cost, but could be triple;
780                the extra energy is spent even if that results in not
781                having enough to cast (which also uses the move) */
782             else if (u.uen < energy)
783                 u.uen = energy;
784         } else if (u.uhunger <= 10) {
785 /*JP
786             cantdoit = "are too weak from hunger";
787 */
788             cantdoit = "\82É\82Í\82¨\82È\82©\82ª\8bó\82«\82·\82¬\82Ä\82¢\82é";
789         } else if (ACURR(A_STR) < 4) {
790 /*JP
791             cantdoit = "lack the strength";
792 */
793             cantdoit = "\82¾\82¯\82Ì\97Í\82ª\82È\82¢";
794         } else if (energy > u.uen) {
795 /*JP
796             cantdoit = "lack the energy";
797 */
798             cantdoit = "\82¾\82¯\82Ì\83G\83l\83\8b\83M\81[\82ª\82È\82¢";
799         }
800         if (cantdoit) {
801 #if 0 /*JP:T*/
802             You("%s %s.", cantdoit,
803                 castit ? "for a teleport spell" : "to teleport");
804 #else
805             You("%s%s\81D", cantdoit,
806                 castit ? "\8fu\8aÔ\88Ú\93®\82Ì\96\82\96@\82ð\8f¥\82¦\82é" : "\8fu\8aÔ\88Ú\93®\82·\82é");
807 #endif
808             return 0;
809         } else if (check_capacity(
810 /*JP
811                        "Your concentration falters from carrying so much.")) {
812 */
813                        "\91ò\8eR\82à\82Ì\82ð\8e\9d\82¿\82·\82¬\82Ä\8fW\92\86\82Å\82«\82È\82¢\81D")) {
814             return 1; /* this failure in spelleffects() also uses the move */
815         }
816
817         if (castit) {
818             /* energy cost is deducted in spelleffects() */
819             exercise(A_WIS, TRUE);
820             if (spelleffects(sp_no, TRUE))
821                 return 1;
822             else if (!break_the_rules)
823                 return 0;
824         } else {
825             /* bypassing spelleffects(); apply energy cost directly */
826             u.uen -= energy;
827             context.botl = 1;
828         }
829     }
830
831     if (next_to_u()) {
832         if (trap && trap_once)
833             vault_tele();
834         else
835             tele();
836         (void) next_to_u();
837     } else {
838         You("%s", shudder_for_moment);
839         return 0;
840     }
841     if (!trap)
842         morehungry(100);
843     return 1;
844 }
845
846 void
847 level_tele()
848 {
849     register int newlev;
850     d_level newlevel;
851     const char *escape_by_flying = 0; /* when surviving dest of -N */
852     char buf[BUFSZ];
853     boolean force_dest = FALSE;
854
855     if (iflags.debug_fuzzer)
856         goto random_levtport;
857     if ((u.uhave.amulet || In_endgame(&u.uz) || In_sokoban(&u.uz))
858         && !wizard) {
859 /*JP
860         You_feel("very disoriented for a moment.");
861 */
862         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81D");
863         return;
864     }
865     if ((Teleport_control && !Stunned) || wizard) {
866         char qbuf[BUFSZ];
867         int trycnt = 0;
868
869 /*JP
870         Strcpy(qbuf, "To what level do you want to teleport?");
871 */
872         Strcpy(qbuf, "\89½\8aK\82É\88Ú\93®\82µ\82Ü\82·\82©\81H");
873         do {
874             if (iflags.menu_requested) {
875                 /* wizard mode 'm ^V' skips prompting on first pass
876                    (note: level Tport via menu won't have any second pass) */
877                 iflags.menu_requested = FALSE;
878                 if (wizard)
879                     goto levTport_menu;
880             }
881             if (++trycnt == 2) {
882                 if (wizard)
883 /*JP
884                     Strcat(qbuf, " [type a number, name, or ? for a menu]");
885 */
886                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë\81D?\82Å\83\81\83j\83\85\81[]");
887                 else
888 /*JP
889                     Strcat(qbuf, " [type a number or name]");
890 */
891                     Strcat(qbuf, " [\90\94\8e\9a\82©\96¼\91O\82ð\82¢\82ê\82Ä\82Ë]");
892             }
893             *buf = '\0'; /* EDIT_GETLIN: if we're on second or later pass,
894                             the previous input was invalid so don't use it
895                             as getlin()'s preloaded default answer */
896             getlin(qbuf, buf);
897             if (!strcmp(buf, "\033")) { /* cancelled */
898                 if (Confusion && rnl(5)) {
899 /*JP
900                     pline("Oops...");
901 */
902                     pline("\82¨\82Á\82Æ\81D\81D\81D");
903                     goto random_levtport;
904                 }
905                 return;
906             } else if (!strcmp(buf, "*")) {
907                 goto random_levtport;
908             } else if (Confusion && rnl(5)) {
909 /*JP
910                 pline("Oops...");
911 */
912                 pline("\82¨\82Á\82Æ\81D\81D\81D");
913                 goto random_levtport;
914             }
915             if (wizard && !strcmp(buf, "?")) {
916                 schar destlev;
917                 xchar destdnum;
918
919  levTport_menu:
920                 destlev = 0;
921                 destdnum = 0;
922                 newlev = (int) print_dungeon(TRUE, &destlev, &destdnum);
923                 if (!newlev)
924                     return;
925
926                 newlevel.dnum = destdnum;
927                 newlevel.dlevel = destlev;
928                 if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
929                     struct obj *amu;
930
931                     if (!u.uhave.amulet
932                         && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
933                                != 0) {
934                         /* ordinarily we'd use hold_another_object()
935                            for something like this, but we don't want
936                            fumbling or already full pack to interfere */
937                         amu = addinv(amu);
938                         prinv("Endgame prerequisite:", amu, 0L);
939                     }
940                 }
941                 force_dest = TRUE;
942             } else if ((newlev = lev_by_name(buf)) == 0)
943                 newlev = atoi(buf);
944         } while (!newlev && !digit(buf[0])
945                  && (buf[0] != '-' || !digit(buf[1])) && trycnt < 10);
946
947         /* no dungeon escape via this route */
948         if (newlev == 0) {
949             if (trycnt >= 10)
950                 goto random_levtport;
951 /*JP
952             if (ynq("Go to Nowhere.  Are you sure?") != 'y')
953 */
954             if (ynq("\82Ç\82±\82Æ\82à\92m\82ê\82Ê\8fê\8f\8a\82É\8ds\82«\82Ü\82·\81D\82æ\82ë\82µ\82¢\82Å\82·\82©\81H") != 'y')
955                 return;
956 #if 0 /*JP:T*/
957             You("%s in agony as your body begins to warp...",
958                 is_silent(youmonst.data) ? "writhe" : "scream");
959 #else
960             You("\91Ì\82ª\88Ú\93®\82µ\82Í\82\82ß\82é\82Æ\81C\8bê\82µ\82Ý%s\81D\81D\81D",
961                 is_silent(youmonst.data) ? "\82Å\90g\82à\82¾\82¦\82µ\82½" : "\82Ì\82 \82¦\82¬\90º\82ð\8fo\82µ\82½");
962 #endif
963             display_nhwindow(WIN_MESSAGE, FALSE);
964 /*JP
965             You("cease to exist.");
966 */
967             Your("\91\8dÝ\82Í\8fÁ\96Å\82µ\82½\81D");
968             if (invent)
969 /*JP
970                 Your("possessions land on the %s with a thud.",
971 */
972                 Your("\8e\9d\82¿\82à\82Ì\82Í\83h\83T\83b\82Æ%s\82É\97\8e\82¿\82½\81D",
973                      surface(u.ux, u.uy));
974             killer.format = NO_KILLER_PREFIX;
975 /*JP
976             Strcpy(killer.name, "committed suicide");
977 */
978             Strcpy(killer.name, "\8e©\8eE\82µ\82½");
979             done(DIED);
980 /*JP
981             pline("An energized cloud of dust begins to coalesce.");
982 */
983             pline("\83G\83l\83\8b\83M\81[\82ð\82à\82Á\82½\82Ù\82±\82è\82Ì\89Q\82ª\8c\8b\8d\87\82µ\82Í\82\82ß\82½\81D");
984 #if 0 /*JP:T*/
985             Your("body rematerializes%s.",
986                  invent ? ", and you gather up all your possessions" : "");
987 #else
988             Your("\91Ì\82Í\8dÄ\82Ñ\8eÀ\91Ì\89»\82µ\82½\81D%s",
989                  invent ? "\82»\82µ\82Ä\91S\82Ä\82Ì\8e\9d\82¿\95¨\82ð\8fE\82¢\8fã\82°\82½\81D" : "");
990 #endif
991             return;
992         }
993
994         /* if in Knox and the requested level > 0, stay put.
995          * we let negative values requests fall into the "heaven" loop.
996          */
997         if (Is_knox(&u.uz) && newlev > 0 && !force_dest) {
998             You1(shudder_for_moment);
999             return;
1000         }
1001         /* if in Quest, the player sees "Home 1", etc., on the status
1002          * line, instead of the logical depth of the level.  controlled
1003          * level teleport request is likely to be relativized to the
1004          * status line, and consequently it should be incremented to
1005          * the value of the logical depth of the target level.
1006          *
1007          * we let negative values requests fall into the "heaven" loop.
1008          */
1009         if (In_quest(&u.uz) && newlev > 0)
1010             newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
1011     } else { /* involuntary level tele */
1012  random_levtport:
1013         newlev = random_teleport_level();
1014         if (newlev == depth(&u.uz)) {
1015             You1(shudder_for_moment);
1016             return;
1017         }
1018     }
1019
1020     if (u.utrap && u.utraptype == TT_BURIEDBALL)
1021         buried_ball_to_punishment();
1022
1023     if (!next_to_u() && !force_dest) {
1024         You1(shudder_for_moment);
1025         return;
1026     }
1027     if (In_endgame(&u.uz)) { /* must already be wizard */
1028         int llimit = dunlevs_in_dungeon(&u.uz);
1029
1030         if (newlev >= 0 || newlev <= -llimit) {
1031 /*JP
1032             You_cant("get there from here.");
1033 */
1034             You("\82»\82±\82É\82Í\8ds\82¯\82È\82¢\81D");
1035             return;
1036         }
1037         newlevel.dnum = u.uz.dnum;
1038         newlevel.dlevel = llimit + newlev;
1039         schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1040         return;
1041     }
1042
1043     killer.name[0] = 0; /* still alive, so far... */
1044
1045     if (iflags.debug_fuzzer && newlev < 0)
1046         goto random_levtport;
1047     if (newlev < 0 && !force_dest) {
1048         if (*u.ushops0) {
1049             /* take unpaid inventory items off of shop bills */
1050             in_mklev = TRUE; /* suppress map update */
1051             u_left_shop(u.ushops0, TRUE);
1052             /* you're now effectively out of the shop */
1053             *u.ushops0 = *u.ushops = '\0';
1054             in_mklev = FALSE;
1055         }
1056         if (newlev <= -10) {
1057 /*JP
1058             You("arrive in heaven.");
1059 */
1060             You("\93V\8d\91\82É\92H\82è\82Â\82¢\82½\81D");
1061 /*JP
1062             verbalize("Thou art early, but we'll admit thee.");
1063 */
1064             verbalize("\93ð\81C\8e\80\82Ê\82É\82Í\91\81\82·\82¬\82é\82ª\82»\82ê\82à\82æ\82©\82ë\82¤\81D");
1065             killer.format = NO_KILLER_PREFIX;
1066 /*JP
1067             Strcpy(killer.name, "went to heaven prematurely");
1068 */
1069             Strcpy(killer.name, "\8eá\82­\82µ\82Ä\93V\8d\91\82É\8ds\82Á\82½");
1070         } else if (newlev == -9) {
1071 /*JP
1072             You_feel("deliriously happy.");
1073 */
1074             You("\8b\82Á\82½\82æ\82¤\82È\8dK\82¹\82ð\8a´\82\82½\81D");
1075 /*JP
1076             pline("(In fact, you're on Cloud 9!)");
1077 */
1078             pline("(\96{\93\96\82É\8bê\82ð\8fæ\82è\89z\82¦\82½\8fê\8f\8a\82É\82¢\82é\81I) ");
1079             display_nhwindow(WIN_MESSAGE, FALSE);
1080         } else
1081 /*JP
1082             You("are now high above the clouds...");
1083 */
1084             You("\89_\82Ì\97y\82©\8fã\82É\82¢\82é\81D\81D\81D");
1085
1086         if (killer.name[0]) {
1087             ; /* arrival in heaven is pending */
1088         } else if (Levitation) {
1089 /*JP
1090             escape_by_flying = "float gently down to earth";
1091 */
1092             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1093         } else if (Flying) {
1094 /*JP
1095             escape_by_flying = "fly down to the ground";
1096 */
1097             escape_by_flying = "\82ä\82Á\82­\82è\92n\96Ê\82É\8d~\82è\82½\81D";
1098         } else {
1099 /*JP
1100             pline("Unfortunately, you don't know how to fly.");
1101 */
1102             pline("\8ec\94O\82È\82ª\82ç\81C\82 \82È\82½\82Í\94ò\82Ñ\82©\82½\82ð\92m\82ç\82È\82¢\81D");
1103 /*JP
1104             You("plummet a few thousand feet to your death.");
1105 */
1106             pline("\90\94\90ç\83t\83B\81[\83g\82Ì\8e\80\82Ì\83_\83C\83r\83\93\83O\82¾\81I");
1107 #if 0 /*JP*/
1108             Sprintf(killer.name,
1109                     "teleported out of the dungeon and fell to %s death",
1110                     uhis());
1111             killer.format = NO_KILLER_PREFIX;
1112 #else
1113             Strcpy(killer.name, "\96À\8b{\82ð\94ò\82Ñ\82¾\82µ\83_\83C\83r\83\93\83O\82µ\82Ä");
1114             killer.format = KILLED_BY;
1115 #endif
1116         }
1117     }
1118
1119     if (killer.name[0]) { /* the chosen destination was not survivable */
1120         d_level lsav;
1121
1122         /* set specific death location; this also suppresses bones */
1123         lsav = u.uz;   /* save current level, see below */
1124         u.uz.dnum = 0; /* main dungeon */
1125         u.uz.dlevel = (newlev <= -10) ? -10 : 0; /* heaven or surface */
1126         done(DIED);
1127         /* can only get here via life-saving (or declining to die in
1128            explore|debug mode); the hero has now left the dungeon... */
1129 /*JP
1130         escape_by_flying = "find yourself back on the surface";
1131 */
1132         escape_by_flying = "\8bC\82ª\82Â\82¢\82½\82ç\92n\8fã\82É\96ß\82Á\82Ä\82¢\82½";
1133         u.uz = lsav; /* restore u.uz so escape code works */
1134     }
1135
1136     /* calls done(ESCAPED) if newlevel==0 */
1137     if (escape_by_flying) {
1138 /*JP
1139         You("%s.", escape_by_flying);
1140 */
1141         You("%s\81D", escape_by_flying);
1142         newlevel.dnum = 0;   /* specify main dungeon */
1143         newlevel.dlevel = 0; /* escape the dungeon */
1144         /* [dlevel used to be set to 1, but it doesn't make sense to
1145             teleport out of the dungeon and float or fly down to the
1146             surface but then actually arrive back inside the dungeon] */
1147     } else if (u.uz.dnum == medusa_level.dnum
1148                && newlev >= dungeons[u.uz.dnum].depth_start
1149                                 + dunlevs_in_dungeon(&u.uz)) {
1150         if (!(wizard && force_dest))
1151             find_hell(&newlevel);
1152     } else {
1153         /* if invocation did not yet occur, teleporting into
1154          * the last level of Gehennom is forbidden.
1155          */
1156         if (!wizard && Inhell && !u.uevent.invoked
1157             && newlev >= (dungeons[u.uz.dnum].depth_start
1158                           + dunlevs_in_dungeon(&u.uz) - 1)) {
1159             newlev = dungeons[u.uz.dnum].depth_start
1160                      + dunlevs_in_dungeon(&u.uz) - 2;
1161 /*JP
1162             pline("Sorry...");
1163 */
1164             pline("\82¨\82Á\82Æ\81D\81D\81D");
1165         }
1166         /* no teleporting out of quest dungeon */
1167         if (In_quest(&u.uz) && newlev < depth(&qstart_level))
1168             newlev = depth(&qstart_level);
1169         /* the player thinks of levels purely in logical terms, so
1170          * we must translate newlev to a number relative to the
1171          * current dungeon.
1172          */
1173         if (!(wizard && force_dest))
1174             get_level(&newlevel, newlev);
1175     }
1176     schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0);
1177     /* in case player just read a scroll and is about to be asked to
1178        call it something, we can't defer until the end of the turn */
1179     if (u.utotype && !context.mon_moving)
1180         deferred_goto();
1181 }
1182
1183 void
1184 domagicportal(ttmp)
1185 register struct trap *ttmp;
1186 {
1187     struct d_level target_level;
1188
1189     if (u.utrap && u.utraptype == TT_BURIEDBALL)
1190         buried_ball_to_punishment();
1191
1192     if (!next_to_u()) {
1193         You1(shudder_for_moment);
1194         return;
1195     }
1196
1197     /* if landed from another portal, do nothing */
1198     /* problem: level teleport landing escapes the check */
1199     if (!on_level(&u.uz, &u.uz0))
1200         return;
1201
1202 /*JP
1203     You("activated a magic portal!");
1204 */
1205     pline("\96\82\96@\82Ì\93ü\8cû\82ª\8dì\93®\82µ\82½\81I");
1206
1207     /* prevent the poor shnook, whose amulet was stolen while in
1208      * the endgame, from accidently triggering the portal to the
1209      * next level, and thus losing the game
1210      */
1211     if (In_endgame(&u.uz) && !u.uhave.amulet) {
1212 /*JP
1213         You_feel("dizzy for a moment, but nothing happens...");
1214 */
1215         You("\88ê\8fu\82ß\82Ü\82¢\82ð\8a´\82\82½\81C\82µ\82©\82µ\89½\82à\8bN\82«\82È\82©\82Á\82½\81D\81D\81D");
1216         return;
1217     }
1218
1219     target_level = ttmp->dst;
1220     schedule_goto(&target_level, FALSE, FALSE, 1,
1221 /*JP
1222                   "You feel dizzy for a moment, but the sensation passes.",
1223 */
1224                   "\88ê\8fu\82ß\82Ü\82¢\82ð\8a´\82\82½\81C\82µ\82©\82µ\82»\82Ì\8a´\8ao\82Í\8fÁ\82¦\82½\81D",
1225                   (char *) 0);
1226 }
1227
1228 void
1229 tele_trap(trap)
1230 struct trap *trap;
1231 {
1232     if (In_endgame(&u.uz) || Antimagic) {
1233         if (Antimagic)
1234             shieldeff(u.ux, u.uy);
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     } else if (!next_to_u()) {
1240         You1(shudder_for_moment);
1241     } else if (trap->once) {
1242         deltrap(trap);
1243         newsym(u.ux, u.uy); /* get rid of trap symbol */
1244         vault_tele();
1245     } else
1246         tele();
1247 }
1248
1249 void
1250 level_tele_trap(trap, trflags)
1251 struct trap *trap;
1252 unsigned trflags;
1253 {
1254 #if 0 /*JP*/
1255     char verbbuf[BUFSZ];
1256
1257     if ((trflags & VIASITTING) != 0)
1258         Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
1259     else
1260         Sprintf(verbbuf, "%s onto",
1261                 Levitation ? (const char *) "float"
1262                            : locomotion(youmonst.data, "step"));
1263     You("%s a level teleport trap!", verbbuf);
1264 #else
1265     if ((trflags & VIASITTING) != 0) {
1266         pline("\95Ê\82Ì\8aK\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82ª\94­\93®\82µ\82½\81I");
1267     } else {
1268         You("\95Ê\82Ì\8aK\82Ö\82Ì\8fu\8aÔ\88Ú\93®\82Ìã©\82ð%s\81I",
1269             Levitation ? (const char *) "\8c©\89º\82ë\82µ\82½"
1270                        : jpast(locomotion(youmonst.data, "\93¥\82Þ")));
1271     }
1272 #endif
1273
1274     if (Antimagic) {
1275         shieldeff(u.ux, u.uy);
1276     }
1277     if (Antimagic || In_endgame(&u.uz)) {
1278 /*JP
1279         You_feel("a wrenching sensation.");
1280 */
1281         You("\82Ë\82\82ç\82ê\82½\82æ\82¤\82È\8a´\8ao\82ð\8a´\82\82½\81D");
1282         return;
1283     }
1284     if (!Blind)
1285 /*JP
1286         You("are momentarily blinded by a flash of light.");
1287 */
1288         You("\82Ü\82Î\82ä\82¢\8cõ\82Å\88ê\8fu\96Ú\82ª\82­\82ç\82ñ\82¾\81D");
1289     else
1290 /*JP
1291         You("are momentarily disoriented.");
1292 */
1293         You("\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\81D");
1294     deltrap(trap);
1295     newsym(u.ux, u.uy); /* get rid of trap symbol */
1296     level_tele();
1297 }
1298
1299 /* check whether monster can arrive at location <x,y> via Tport (or fall) */
1300 STATIC_OVL boolean
1301 rloc_pos_ok(x, y, mtmp)
1302 register int x, y; /* coordinates of candidate location */
1303 struct monst *mtmp;
1304 {
1305     register int xx, yy;
1306
1307     if (!goodpos(x, y, mtmp, 0))
1308         return FALSE;
1309     /*
1310      * Check for restricted areas present in some special levels.
1311      *
1312      * `xx' is current column; if 0, then `yy' will contain flag bits
1313      * rather than row:  bit #0 set => moving upwards; bit #1 set =>
1314      * inside the Wizard's tower.
1315      */
1316     xx = mtmp->mx;
1317     yy = mtmp->my;
1318     if (!xx) {
1319         /* no current location (migrating monster arrival) */
1320         if (dndest.nlx && On_W_tower_level(&u.uz))
1321             return (((yy & 2) != 0)
1322                     /* inside xor not within */
1323                     ^ !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1324                                            dndest.nhx, dndest.nhy));
1325         if (updest.lx && (yy & 1) != 0) /* moving up */
1326             return (within_bounded_area(x, y, updest.lx, updest.ly,
1327                                         updest.hx, updest.hy)
1328                     && (!updest.nlx
1329                         || !within_bounded_area(x, y, updest.nlx, updest.nly,
1330                                                 updest.nhx, updest.nhy)));
1331         if (dndest.lx && (yy & 1) == 0) /* moving down */
1332             return (within_bounded_area(x, y, dndest.lx, dndest.ly,
1333                                         dndest.hx, dndest.hy)
1334                     && (!dndest.nlx
1335                         || !within_bounded_area(x, y, dndest.nlx, dndest.nly,
1336                                                 dndest.nhx, dndest.nhy)));
1337     } else {
1338         /* [try to] prevent a shopkeeper or temple priest from being
1339            sent out of his room (caller might resort to goodpos() if
1340            we report failure here, so this isn't full prevention) */
1341         if (mtmp->isshk && inhishop(mtmp)) {
1342             if (levl[x][y].roomno != ESHK(mtmp)->shoproom)
1343                 return FALSE;
1344         } else if (mtmp->ispriest && inhistemple(mtmp)) {
1345             if (levl[x][y].roomno != EPRI(mtmp)->shroom)
1346                 return FALSE;
1347         }
1348         /* current location is <xx,yy> */
1349         if (!tele_jump_ok(xx, yy, x, y))
1350             return FALSE;
1351     }
1352     /* <x,y> is ok */
1353     return TRUE;
1354 }
1355
1356 /*
1357  * rloc_to()
1358  *
1359  * Pulls a monster from its current position and places a monster at
1360  * a new x and y.  If oldx is 0, then the monster was not in the
1361  * levels.monsters array.  However, if oldx is 0, oldy may still have
1362  * a value because mtmp is a migrating_mon.  Worm tails are always
1363  * placed randomly around the head of the worm.
1364  */
1365 void
1366 rloc_to(mtmp, x, y)
1367 struct monst *mtmp;
1368 register int x, y;
1369 {
1370     register int oldx = mtmp->mx, oldy = mtmp->my;
1371     boolean resident_shk = mtmp->isshk && inhishop(mtmp);
1372
1373     if (x == mtmp->mx && y == mtmp->my && m_at(x, y) == mtmp)
1374         return; /* that was easy */
1375
1376     if (oldx) { /* "pick up" monster */
1377         if (mtmp->wormno) {
1378             remove_worm(mtmp);
1379         } else {
1380             remove_monster(oldx, oldy);
1381             newsym(oldx, oldy); /* update old location */
1382         }
1383     }
1384
1385     memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
1386     place_monster(mtmp, x, y); /* put monster down */
1387     update_monster_region(mtmp);
1388
1389     if (mtmp->wormno) /* now put down tail */
1390         place_worm_tail_randomly(mtmp, x, y);
1391
1392     if (u.ustuck == mtmp) {
1393         if (u.uswallow) {
1394             u_on_newpos(mtmp->mx, mtmp->my);
1395             docrt();
1396         } else if (distu(mtmp->mx, mtmp->my) > 2) {
1397            unstuck(mtmp);
1398         }
1399     }
1400
1401     newsym(x, y);      /* update new location */
1402     set_apparxy(mtmp); /* orient monster */
1403
1404     /* shopkeepers will only teleport if you zap them with a wand of
1405        teleportation or if they've been transformed into a jumpy monster;
1406        the latter only happens if you've attacked them with polymorph */
1407     if (resident_shk && !inhishop(mtmp))
1408         make_angry_shk(mtmp, oldx, oldy);
1409 }
1410
1411 /* place a monster at a random location, typically due to teleport */
1412 /* return TRUE if successful, FALSE if not */
1413 boolean
1414 rloc(mtmp, suppress_impossible)
1415 struct monst *mtmp; /* mx==0 implies migrating monster arrival */
1416 boolean suppress_impossible;
1417 {
1418     register int x, y, trycount;
1419
1420     if (mtmp == u.usteed) {
1421         tele();
1422         return TRUE;
1423     }
1424
1425     if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */
1426         if (!In_W_tower(u.ux, u.uy, &u.uz))
1427             x = xupstair, y = yupstair;
1428         else if (!xdnladder) /* bottom level of tower */
1429             x = xupladder, y = yupladder;
1430         else
1431             x = xdnladder, y = ydnladder;
1432         /* if the wiz teleports away to heal, try the up staircase,
1433            to block the player's escaping before he's healed
1434            (deliberately use `goodpos' rather than `rloc_pos_ok' here) */
1435         if (goodpos(x, y, mtmp, 0))
1436             goto found_xy;
1437     }
1438
1439     trycount = 0;
1440     do {
1441         x = rn1(COLNO - 3, 2);
1442         y = rn2(ROWNO);
1443         if ((trycount < 500) ? rloc_pos_ok(x, y, mtmp)
1444                              : goodpos(x, y, mtmp, 0))
1445             goto found_xy;
1446     } while (++trycount < 1000);
1447
1448     /* last ditch attempt to find a good place */
1449     for (x = 2; x < COLNO - 1; x++)
1450         for (y = 0; y < ROWNO; y++)
1451             if (goodpos(x, y, mtmp, 0))
1452                 goto found_xy;
1453
1454     /* level either full of monsters or somehow faulty */
1455     if (!suppress_impossible)
1456         impossible("rloc(): couldn't relocate monster");
1457     return FALSE;
1458
1459  found_xy:
1460     rloc_to(mtmp, x, y);
1461     return TRUE;
1462 }
1463
1464 STATIC_OVL void
1465 mvault_tele(mtmp)
1466 struct monst *mtmp;
1467 {
1468     struct mkroom *croom = search_special(VAULT);
1469     coord c;
1470
1471     if (croom && somexy(croom, &c) && goodpos(c.x, c.y, mtmp, 0)) {
1472         rloc_to(mtmp, c.x, c.y);
1473         return;
1474     }
1475     (void) rloc(mtmp, TRUE);
1476 }
1477
1478 boolean
1479 tele_restrict(mon)
1480 struct monst *mon;
1481 {
1482     if (level.flags.noteleport) {
1483         if (canseemon(mon))
1484 #if 0 /*JP:T*/
1485             pline("A mysterious force prevents %s from teleporting!",
1486                   mon_nam(mon));
1487 #else
1488             pline("\8aï\96­\82È\97Í\82ª%s\82Ì\8fu\8aÔ\88Ú\93®\82ð\96h\82¢\82¾\81I",
1489                   mon_nam(mon));
1490 #endif
1491         return TRUE;
1492     }
1493     return FALSE;
1494 }
1495
1496 void
1497 mtele_trap(mtmp, trap, in_sight)
1498 struct monst *mtmp;
1499 struct trap *trap;
1500 int in_sight;
1501 {
1502     char *monname;
1503
1504     if (tele_restrict(mtmp))
1505         return;
1506     if (teleport_pet(mtmp, FALSE)) {
1507         /* save name with pre-movement visibility */
1508         monname = Monnam(mtmp);
1509
1510         /* Note: don't remove the trap if a vault.  Other-
1511          * wise the monster will be stuck there, since
1512          * the guard isn't going to come for it...
1513          */
1514         if (trap->once)
1515             mvault_tele(mtmp);
1516         else
1517             (void) rloc(mtmp, TRUE);
1518
1519         if (in_sight) {
1520             if (canseemon(mtmp))
1521 /*JP
1522                 pline("%s seems disoriented.", monname);
1523 */
1524                 pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\8e¸\82Á\82½\82æ\82¤\82¾\81D", monname);
1525             else
1526 /*JP
1527                 pline("%s suddenly disappears!", monname);
1528 */
1529                 pline("%s\82Í\93Ë\91R\8fÁ\82¦\82½\81I", monname);
1530             seetrap(trap);
1531         }
1532     }
1533 }
1534
1535 /* return 0 if still on level, 3 if not */
1536 int
1537 mlevel_tele_trap(mtmp, trap, force_it, in_sight)
1538 struct monst *mtmp;
1539 struct trap *trap;
1540 boolean force_it;
1541 int in_sight;
1542 {
1543     int tt = (trap ? trap->ttyp : NO_TRAP);
1544
1545     if (mtmp == u.ustuck) /* probably a vortex */
1546         return 0;         /* temporary? kludge */
1547     if (teleport_pet(mtmp, force_it)) {
1548         d_level tolevel;
1549         int migrate_typ = MIGR_RANDOM;
1550
1551         if (is_hole(tt)) {
1552             if (Is_stronghold(&u.uz)) {
1553                 assign_level(&tolevel, &valley_level);
1554             } else if (Is_botlevel(&u.uz)) {
1555                 if (in_sight && trap->tseen)
1556 #if 0 /*JP:T*/
1557                     pline("%s avoids the %s.", Monnam(mtmp),
1558                           (tt == HOLE) ? "hole" : "trap");
1559 #else
1560                     pline("%s\82Í%s\82ð\89ñ\94ð\82µ\82½\81D", Monnam(mtmp),
1561                           (tt == HOLE) ? "\8c\8a" : "ã©");
1562 #endif
1563                 return 0;
1564             } else {
1565                 get_level(&tolevel, depth(&u.uz) + 1);
1566             }
1567         } else if (tt == MAGIC_PORTAL) {
1568             if (In_endgame(&u.uz) && (mon_has_amulet(mtmp)
1569                                       || is_home_elemental(mtmp->data)
1570                                       || rn2(7))) {
1571                 if (in_sight && mtmp->data->mlet != S_ELEMENTAL) {
1572 /*JP
1573                     pline("%s seems to shimmer for a moment.", Monnam(mtmp));
1574 */
1575                     pline("%s\82ª\88ê\8fu\8bP\82¢\82½\82æ\82¤\82É\8c©\82¦\82½\81D", Monnam(mtmp));
1576                     seetrap(trap);
1577                 }
1578                 return 0;
1579             } else {
1580                 assign_level(&tolevel, &trap->dst);
1581                 migrate_typ = MIGR_PORTAL;
1582             }
1583         } else if (tt == LEVEL_TELEP || tt == NO_TRAP) {
1584             int nlev;
1585
1586             if (mon_has_amulet(mtmp) || In_endgame(&u.uz)
1587                 /* NO_TRAP is used when forcing a monster off the level;
1588                    onscary(0,0,) is true for the Wizard, Riders, lawful
1589                    minions, Angels of any alignment, shopkeeper or priest
1590                    currently inside his or her own special room */
1591                 || (tt == NO_TRAP && onscary(0, 0, mtmp))) {
1592                 if (in_sight)
1593 /*JP
1594                     pline("%s seems very disoriented for a moment.",
1595 */
1596                     pline("%s\82Í\88ê\8fu\95û\8cü\8a´\8ao\82ð\91å\82«\82­\8e¸\82Á\82½\82æ\82¤\82¾\81D",
1597                           Monnam(mtmp));
1598                 return 0;
1599             }
1600             if (tt == NO_TRAP) {
1601                 /* creature is being forced off the level to make room;
1602                    it will try to return to this level (at a random spot
1603                    rather than its current one) if the level is left by
1604                    the hero and then revisited */
1605                 assign_level(&tolevel, &u.uz);
1606             } else {
1607                 nlev = random_teleport_level();
1608                 if (nlev == depth(&u.uz)) {
1609                     if (in_sight)
1610 /*JP
1611                         pline("%s shudders for a moment.", Monnam(mtmp));
1612 */
1613                         pline("%s\82Í\88ê\8fu\90k\82¦\82½\81D", Monnam(mtmp));
1614                     return 0;
1615                 }
1616                 get_level(&tolevel, nlev);
1617             }
1618         } else {
1619             impossible("mlevel_tele_trap: unexpected trap type (%d)", tt);
1620             return 0;
1621         }
1622
1623         if (in_sight) {
1624 /*JP
1625             pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
1626 */
1627             pline("\93Ë\91R%s\82ª\8e\8b\8aE\82©\82ç\8fÁ\82¦\82½\81D", mon_nam(mtmp));
1628             if (trap)
1629                 seetrap(trap);
1630         }
1631         migrate_to_level(mtmp, ledger_no(&tolevel), migrate_typ, (coord *) 0);
1632         return 3; /* no longer on this level */
1633     }
1634     return 0;
1635 }
1636
1637 /* place object randomly, returns False if it's gone (eg broken) */
1638 boolean
1639 rloco(obj)
1640 register struct obj *obj;
1641 {
1642     register xchar tx, ty, otx, oty;
1643     boolean restricted_fall;
1644     int try_limit = 4000;
1645
1646     if (obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm])) {
1647         if (revive_corpse(obj))
1648             return FALSE;
1649     }
1650
1651     obj_extract_self(obj);
1652     otx = obj->ox;
1653     oty = obj->oy;
1654     restricted_fall = (otx == 0 && dndest.lx);
1655     do {
1656         tx = rn1(COLNO - 3, 2);
1657         ty = rn2(ROWNO);
1658         if (!--try_limit)
1659             break;
1660     } while (!goodpos(tx, ty, (struct monst *) 0, 0)
1661              || (restricted_fall
1662                  && (!within_bounded_area(tx, ty, dndest.lx, dndest.ly,
1663                                           dndest.hx, dndest.hy)
1664                      || (dndest.nlx
1665                          && within_bounded_area(tx, ty,
1666                                                 dndest.nlx, dndest.nly,
1667                                                 dndest.nhx, dndest.nhy))))
1668              /* on the Wizard Tower levels, objects inside should
1669                 stay inside and objects outside should stay outside */
1670              || (dndest.nlx && On_W_tower_level(&u.uz)
1671                  && within_bounded_area(tx, ty, dndest.nlx, dndest.nly,
1672                                         dndest.nhx, dndest.nhy)
1673                     != within_bounded_area(otx, oty, dndest.nlx, dndest.nly,
1674                                            dndest.nhx, dndest.nhy)));
1675
1676 /*JP
1677     if (flooreffects(obj, tx, ty, "fall")) {
1678 */
1679     if (flooreffects(obj, tx, ty, "\97\8e\82¿\82é")) {
1680         /* update old location since flooreffects() couldn't;
1681            unblock_point() for boulder handled by obj_extract_self() */
1682         newsym(otx, oty);
1683         return FALSE;
1684     } else if (otx == 0 && oty == 0) {
1685         ; /* fell through a trap door; no update of old loc needed */
1686     } else {
1687         if (costly_spot(otx, oty)
1688             && (!costly_spot(tx, ty)
1689                 || !index(in_rooms(tx, ty, 0), *in_rooms(otx, oty, 0)))) {
1690             if (costly_spot(u.ux, u.uy)
1691                 && index(u.urooms, *in_rooms(otx, oty, 0)))
1692                 addtobill(obj, FALSE, FALSE, FALSE);
1693             else
1694                 (void) stolen_value(obj, otx, oty, FALSE, FALSE);
1695         }
1696         newsym(otx, oty); /* update old location */
1697     }
1698     place_object(obj, tx, ty);
1699     /* note: block_point() for boulder handled by place_object() */
1700     newsym(tx, ty);
1701     return TRUE;
1702 }
1703
1704 /* Returns an absolute depth */
1705 int
1706 random_teleport_level()
1707 {
1708     int nlev, max_depth, min_depth, cur_depth = (int) depth(&u.uz);
1709
1710     /* [the endgame case can only occur in wizard mode] */
1711     if (!rn2(5) || Is_knox(&u.uz) || In_endgame(&u.uz))
1712         return cur_depth;
1713
1714     /* What I really want to do is as follows:
1715      * -- If in a dungeon that goes down, the new level is to be restricted
1716      *    to [top of parent, bottom of current dungeon]
1717      * -- If in a dungeon that goes up, the new level is to be restricted
1718      *    to [top of current dungeon, bottom of parent]
1719      * -- If in a quest dungeon or similar dungeon entered by portals,
1720      *    the new level is to be restricted to [top of current dungeon,
1721      *    bottom of current dungeon]
1722      * The current behavior is not as sophisticated as that ideal, but is
1723      * still better what we used to do, which was like this for players
1724      * but different for monsters for no obvious reason.  Currently, we
1725      * must explicitly check for special dungeons.  We check for Knox
1726      * above; endgame is handled in the caller due to its different
1727      * message ("disoriented").
1728      * --KAA
1729      * 3.4.2: explicitly handle quest here too, to fix the problem of
1730      * monsters sometimes level teleporting out of it into main dungeon.
1731      * Also prevent monsters reaching the Sanctum prior to invocation.
1732      */
1733     if (In_quest(&u.uz)) {
1734         int bottom = dunlevs_in_dungeon(&u.uz),
1735             qlocate_depth = qlocate_level.dlevel;
1736
1737         /* if hero hasn't reached the middle locate level yet,
1738            no one can randomly teleport past it */
1739         if (dunlev_reached(&u.uz) < qlocate_depth)
1740             bottom = qlocate_depth;
1741         min_depth = dungeons[u.uz.dnum].depth_start;
1742         max_depth = bottom + (dungeons[u.uz.dnum].depth_start - 1);
1743     } else {
1744         min_depth = 1;
1745         max_depth =
1746             dunlevs_in_dungeon(&u.uz) + (dungeons[u.uz.dnum].depth_start - 1);
1747         /* can't reach Sanctum if the invocation hasn't been performed */
1748         if (Inhell && !u.uevent.invoked)
1749             max_depth -= 1;
1750     }
1751
1752     /* Get a random value relative to the current dungeon */
1753     /* Range is 1 to current+3, current not counting */
1754     nlev = rn2(cur_depth + 3 - min_depth) + min_depth;
1755     if (nlev >= cur_depth)
1756         nlev++;
1757
1758     if (nlev > max_depth) {
1759         nlev = max_depth;
1760         /* teleport up if already on bottom */
1761         if (Is_botlevel(&u.uz))
1762             nlev -= rnd(3);
1763     }
1764     if (nlev < min_depth) {
1765         nlev = min_depth;
1766         if (nlev == cur_depth) {
1767             nlev += rnd(3);
1768             if (nlev > max_depth)
1769                 nlev = max_depth;
1770         }
1771     }
1772     return nlev;
1773 }
1774
1775 /* you teleport a monster (via wand, spell, or poly'd q.mechanic attack);
1776    return false iff the attempt fails */
1777 boolean
1778 u_teleport_mon(mtmp, give_feedback)
1779 struct monst *mtmp;
1780 boolean give_feedback;
1781 {
1782     coord cc;
1783
1784     if (mtmp->ispriest && *in_rooms(mtmp->mx, mtmp->my, TEMPLE)) {
1785         if (give_feedback)
1786 /*JP
1787             pline("%s resists your magic!", Monnam(mtmp));
1788 */
1789             pline("%s\82Í\96\82\96@\82ð\96h\82¢\82¾\81I", Monnam(mtmp));
1790         return FALSE;
1791     } else if (level.flags.noteleport && u.uswallow && mtmp == u.ustuck) {
1792         if (give_feedback)
1793 /*JP
1794             You("are no longer inside %s!", mon_nam(mtmp));
1795 */
1796             You("%s\82Ì\93à\95\94\82©\82ç\92E\8fo\82µ\82½\81I", mon_nam(mtmp));
1797         unstuck(mtmp);
1798         (void) rloc(mtmp, TRUE);
1799     } else if (is_rider(mtmp->data) && rn2(13)
1800                && enexto(&cc, u.ux, u.uy, mtmp->data))
1801         rloc_to(mtmp, cc.x, cc.y);
1802     else
1803         (void) rloc(mtmp, TRUE);
1804     return TRUE;
1805 }
1806
1807 /*teleport.c*/