OSDN Git Service

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