OSDN Git Service

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