OSDN Git Service

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