]> granicus.if.org Git - nethack/commitdiff
Merge branch 'master' into derek-farming
authorDerek S. Ray <derekray@gmail.com>
Wed, 1 Apr 2015 21:40:25 +0000 (17:40 -0400)
committerDerek S. Ray <derekray@gmail.com>
Wed, 1 Apr 2015 21:40:25 +0000 (17:40 -0400)
* master: (160 commits)
  Add doors correctly
  bug fixes for nhsub
  Generate oracle monsters after subroom
  Generate minetown guards after subrooms
  ...

Conflicts:
src/do.c
src/files.c
src/hack.c
src/mon.c
src/vision.c

1  2 
include/extern.h
include/obj.h
src/do.c
src/files.c
src/hack.c
src/mon.c
src/vision.c

Simple merge
diff --cc include/obj.h
Simple merge
diff --cc src/do.c
index d253af1330539d34e3497f0c2c0884b7218f62e4,eae360425174e8e5873321a3cf5f89e1bd44eb1e..fcb77525e01423d623fd491525357b82fa1328ba
+++ b/src/do.c
@@@ -1034,382 -1026,382 +1034,382 @@@ boolean at_stairs, falling, portal
         *       -1   11.46  12.50  12.5
         *       -2    5.21   4.17   0.0
         *       -3    2.08   0.0    0.0
 -       */
 -      if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&
 -                              (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
 -              if (!rn2(4)) {
 -                  int odds = 3 + (int)u.ualign.type,          /* 2..4 */
 -                      diff = odds <= 1 ? 0 : rn2(odds);       /* paranoia */
 -
 -                  if (diff != 0) {
 -                      assign_rnd_level(newlevel, &u.uz, diff);
 -                      /* if inside the tower, stay inside */
 -                      if (was_in_W_tower &&
 -                          !On_W_tower_level(newlevel)) diff = 0;
 -                  }
 -                  if (diff == 0)
 -                      assign_level(newlevel, &u.uz);
 -
 -                  new_ledger = ledger_no(newlevel);
 -
 -                  pline("A mysterious force momentarily surrounds you...");
 -                  if (on_level(newlevel, &u.uz)) {
 -                      (void) safe_teleds(FALSE);
 -                      (void) next_to_u();
 -                      return;
 -                  } else
 -                      at_stairs = at_ladder = FALSE;
 -              }
 -      }
 +     */
 +    if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&
 +                (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
 +        if (!rn2(4)) {
 +            int odds = 3 + (int)u.ualign.type,                /* 2..4 */
 +            diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
 +
 +            if (diff != 0) {
 +            assign_rnd_level(newlevel, &u.uz, diff);
 +            /* if inside the tower, stay inside */
 +            if (was_in_W_tower &&
 +                !On_W_tower_level(newlevel)) diff = 0;
 +            }
 +            if (diff == 0)
 +            assign_level(newlevel, &u.uz);
 +
 +            new_ledger = ledger_no(newlevel);
 +
 +            pline("A mysterious force momentarily surrounds you...");
 +            if (on_level(newlevel, &u.uz)) {
 +            (void) safe_teleds(FALSE);
 +            (void) next_to_u();
 +            return;
 +            } else
 +            at_stairs = at_ladder = FALSE;
 +        }
 +    }
  
 -      /* Prevent the player from going past the first quest level unless
 -       * (s)he has been given the go-ahead by the leader.
 -       */
 -      if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) {
 -              pline("A mysterious force prevents you from descending.");
 -              return;
 -      }
 +    /* Prevent the player from going past the first quest level unless
 +     * (s)he has been given the go-ahead by the leader.
 +     */
 +    if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest()) {
 +        pline("A mysterious force prevents you from descending.");
 +        return;
 +    }
  
 -      if (on_level(newlevel, &u.uz)) return;          /* this can happen */
 -
 -      /* tethered movement makes level change while trapped feasible */
 -      if (u.utrap && u.utraptype == TT_BURIEDBALL)
 -          buried_ball_to_punishment(); /* (before we save/leave old level) */
 -
 -      fd = currentlevel_rewrite();
 -      if (fd < 0) return;
 -
 -      if (falling) /* assuming this is only trap door or hole */
 -          impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel);
 -
 -      check_special_room(TRUE);               /* probably was a trap door */
 -      if (Punished) unplacebc();
 -      u.utrap = 0;                            /* needed in level_tele */
 -      fill_pit(u.ux, u.uy);
 -      u.ustuck = 0;                           /* idem */
 -      u.uinwater = 0;
 -      u.uundetected = 0;      /* not hidden, even if means are available */
 -      keepdogs(FALSE);
 -      if (u.uswallow)                         /* idem */
 -              u.uswldtim = u.uswallow = 0;
 -      recalc_mapseen(); /* recalculate map overview before we leave the level */
 -      /*
 -       *  We no longer see anything on the level.  Make sure that this
 -       *  follows u.uswallow set to null since uswallow overrides all
 -       *  normal vision.
 -       */
 -      vision_recalc(2);
 -
 -      /*
 -       * Save the level we're leaving.  If we're entering the endgame,
 -       * we can get rid of all existing levels because they cannot be
 -       * reached any more.  We still need to use savelev()'s cleanup
 -       * for the level being left, to recover dynamic memory in use and
 -       * to avoid dangling timers and light sources.
 -       */
 -      cant_go_back = (newdungeon && In_endgame(newlevel));
 -      if (!cant_go_back) {
 -          update_mlstmv();    /* current monsters are becoming inactive */
 -          bufon(fd);          /* use buffered output */
 -      }
 -      savelev(fd, ledger_no(&u.uz),
 -              cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE));
 -      bclose(fd);
 -      if (cant_go_back) {
 -          /* discard unreachable levels; keep #0 */
 -          for (l_idx = maxledgerno(); l_idx > 0; --l_idx)
 -              delete_levelfile(l_idx);
 -          /* mark #overview data for all dungeon branches as uninteresting */
 -          for (l_idx = 0; l_idx < n_dgns; ++l_idx)
 -              remdun_mapseen(l_idx);
 -      }
 +    if (on_level(newlevel, &u.uz)) return;            /* this can happen */
 +
 +    /* tethered movement makes level change while trapped feasible */
 +    if (u.utrap && u.utraptype == TT_BURIEDBALL)
 +        buried_ball_to_punishment(); /* (before we save/leave old level) */
 +
 +    fd = currentlevel_rewrite();
 +    if (fd < 0) return;
 +
 +    if (falling) /* assuming this is only trap door or hole */
 +        impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel);
 +
 +    check_special_room(TRUE);         /* probably was a trap door */
 +    if (Punished) unplacebc();
 +    u.utrap = 0;                              /* needed in level_tele */
 +    fill_pit(u.ux, u.uy);
 +    u.ustuck = 0;                             /* idem */
 +    u.uinwater = 0;
 +    u.uundetected = 0;        /* not hidden, even if means are available */
 +    keepdogs(FALSE);
 +    if (u.uswallow)                           /* idem */
 +        u.uswldtim = u.uswallow = 0;
 +    recalc_mapseen(); /* recalculate map overview before we leave the level */
 +    /*
 +     *  We no longer see anything on the level.  Make sure that this
 +     *  follows u.uswallow set to null since uswallow overrides all
 +     *  normal vision.
 +     */
 +    vision_recalc(2);
 +
 +    /*
 +     * Save the level we're leaving.  If we're entering the endgame,
 +     * we can get rid of all existing levels because they cannot be
 +     * reached any more.  We still need to use savelev()'s cleanup
 +     * for the level being left, to recover dynamic memory in use and
 +     * to avoid dangling timers and light sources.
 +     */
 +    cant_go_back = (newdungeon && In_endgame(newlevel));
 +    if (!cant_go_back) {
 +        update_mlstmv();      /* current monsters are becoming inactive */
 +        bufon(fd);            /* use buffered output */
 +    }
 +    savelev(fd, ledger_no(&u.uz),
 +        cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE));
 +    bclose(fd);
 +    if (cant_go_back) {
 +        /* discard unreachable levels; keep #0 */
 +        for (l_idx = maxledgerno(); l_idx > 0; --l_idx)
 +        delete_levelfile(l_idx);
 +        /* mark #overview data for all dungeon branches as uninteresting */
 +        for (l_idx = 0; l_idx < n_dgns; ++l_idx)
 +        remdun_mapseen(l_idx);
 +    }
  
 -      if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
 -              assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARY);
 +    if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))
 +        assign_graphics(Is_rogue_level(newlevel) ? ROGUESET : PRIMARY);
  #ifdef USE_TILES
 -      substitute_tiles(newlevel);
 +    substitute_tiles(newlevel);
  #endif
 -      /* record this level transition as a potential seen branch unless using
 -       * some non-standard means of transportation (level teleport).
 -       */
 -      if ((at_stairs || falling || portal) && (u.uz.dnum != newlevel->dnum))
 -              recbranch_mapseen(&u.uz, newlevel);
 -      assign_level(&u.uz0, &u.uz);
 -      assign_level(&u.uz, newlevel);
 -      assign_level(&u.utolev, newlevel);
 -      u.utotype = 0;
 -      if (dunlev_reached(&u.uz) < dunlev(&u.uz))
 -              dunlev_reached(&u.uz) = dunlev(&u.uz);
 -      reset_rndmonst(NON_PM);   /* u.uz change affects monster generation */
 -
 -      /* set default level change destination areas */
 -      /* the special level code may override these */
 -      (void) memset((genericptr_t) &updest, 0, sizeof updest);
 -      (void) memset((genericptr_t) &dndest, 0, sizeof dndest);
 -
 -      if (!(level_info[new_ledger].flags & LFILE_EXISTS)) {
 -              /* entering this level for first time; make it now */
 -              if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) {
 -                  impossible("goto_level: returning to discarded level?");
 -                  level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED);
 -              }
 -              mklev();
 -              new = TRUE;     /* made the level */
 -      } else {
 -              /* returning to previously visited level; reload it */
 -              fd = open_levelfile(new_ledger, whynot);
 -              if (fd < 0) {
 -                      pline1(whynot);
 -                      pline("Probably someone removed it.");
 -                      Strcpy(killer.name, whynot);
 -                      done(TRICKED);
 -                      /* we'll reach here if running in wizard mode */
 -                      error("Cannot continue this game.");
 -              }
 -              minit();        /* ZEROCOMP */
 -              getlev(fd, hackpid, new_ledger, FALSE);
 -              (void) close(fd);
 -              oinit(); /* reassign level dependent obj probabilities */
 -      }
 -      /* do this prior to level-change pline messages */
 -      vision_reset();         /* clear old level's line-of-sight */
 -      vision_full_recalc = 0; /* don't let that reenable vision yet */
 -      flush_screen(-1);       /* ensure all map flushes are postponed */
 -
 -      if (portal && !In_endgame(&u.uz)) {
 -          /* find the portal on the new level */
 -          register struct trap *ttrap;
 -
 -          for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap)
 -              if (ttrap->ttyp == MAGIC_PORTAL) break;
 -
 -          if (!ttrap) panic("goto_level: no corresponding portal!");
 -          seetrap(ttrap);
 -          u_on_newpos(ttrap->tx, ttrap->ty);
 -      } else if (at_stairs && !In_endgame(&u.uz)) {
 -          if (up) {
 -              if (at_ladder)
 -                  u_on_newpos(xdnladder, ydnladder);
 -              else if (newdungeon)
 -                  u_on_sstairs(1);
 -              else
 -                  u_on_dnstairs();
 -              /* you climb up the {stairs|ladder};
 -                 fly up the stairs; fly up along the ladder */
 -              pline("%s %s up%s the %s.",
 -                    (Punished && !Levitation) ? "With great effort you" :
 -                                                "You",
 -                    Flying ? "fly" : "climb",
 -                    (Flying && at_ladder) ? " along" : "",
 -                    at_ladder ? "ladder" : "stairs");
 -          } else {    /* down */
 -              if (at_ladder)
 -                  u_on_newpos(xupladder, yupladder);
 -              else if (newdungeon)
 -                  u_on_sstairs(0);
 -              else
 -                  u_on_upstairs();
 -              if (!u.dz) {
 -                  ;   /* stayed on same level? (no transit effects) */
 -              } else if (Flying) {
 -                  if (flags.verbose)
 -                      You("fly down %s.",
 -                          at_ladder ? "along the ladder" : "the stairs");
 -              } else if (near_capacity() > UNENCUMBERED ||
 -                      Punished || Fumbling) {
 -                  You("fall down the %s.", at_ladder ? "ladder" : "stairs");
 -                  if (Punished) {
 -                      drag_down();
 -                      if (carried(uball)) {
 -                          if (uwep == uball)
 -                              setuwep((struct obj *)0);
 -                          if (uswapwep == uball)
 -                              setuswapwep((struct obj *)0);
 -                          if (uquiver == uball)
 -                              setuqwep((struct obj *)0);
 -                          freeinv(uball);
 -                      }
 -                  }
 -                  /* falling off steed has its own losehp() call */
 -                  if (u.usteed)
 -                      dismount_steed(DISMOUNT_FELL);
 -                  else
 -                      losehp(Maybe_Half_Phys(rnd(3)),
 -                             at_ladder ? "falling off a ladder" :
 -                                         "tumbling down a flight of stairs",
 -                             KILLED_BY);
 -                  selftouch("Falling, you");
 -              } else {        /* ordinary descent */
 -                  if (flags.verbose)
 -                      You("%s.", at_ladder ? "climb down the ladder" :
 -                                             "descend the stairs");
 -              }
 -          }
 -      } else {        /* trap door or level_tele or In_endgame */
 -          u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0));
 -          if (falling) {
 -              if (Punished) ballfall();
 -              selftouch("Falling, you");
 -          }
 -      }
 +    /* record this level transition as a potential seen branch unless using
 +     * some non-standard means of transportation (level teleport).
 +     */
 +    if ((at_stairs || falling || portal) && (u.uz.dnum != newlevel->dnum))
 +        recbranch_mapseen(&u.uz, newlevel);
 +    assign_level(&u.uz0, &u.uz);
 +    assign_level(&u.uz, newlevel);
 +    assign_level(&u.utolev, newlevel);
 +    u.utotype = 0;
 +    if (dunlev_reached(&u.uz) < dunlev(&u.uz))
 +        dunlev_reached(&u.uz) = dunlev(&u.uz);
 +    reset_rndmonst(NON_PM);   /* u.uz change affects monster generation */
 +
 +    /* set default level change destination areas */
 +    /* the special level code may override these */
 +    (void) memset((genericptr_t) &updest, 0, sizeof updest);
 +    (void) memset((genericptr_t) &dndest, 0, sizeof dndest);
 +
 +    if (!(level_info[new_ledger].flags & LFILE_EXISTS)) {
 +        /* entering this level for first time; make it now */
 +        if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) {
 +            impossible("goto_level: returning to discarded level?");
 +            level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED);
 +        }
 +        mklev();
 +        new = TRUE;   /* made the level */
 +    } else {
 +        /* returning to previously visited level; reload it */
 +        fd = open_levelfile(new_ledger, whynot);
 +        if (fd < 0) {
 +            pline1(whynot);
 +            pline("Probably someone removed it.");
 +            Strcpy(killer.name, whynot);
 +            done(TRICKED);
 +            /* we'll reach here if running in wizard mode */
 +            error("Cannot continue this game.");
 +        }
 +        minit();      /* ZEROCOMP */
 +        getlev(fd, hackpid, new_ledger, FALSE);
 +        (void) close(fd);
 +        oinit(); /* reassign level dependent obj probabilities */
 +    }
 +    /* do this prior to level-change pline messages */
 +    vision_reset();           /* clear old level's line-of-sight */
 +    vision_full_recalc = 0;   /* don't let that reenable vision yet */
 +    flush_screen(-1); /* ensure all map flushes are postponed */
 +
 +    if (portal && !In_endgame(&u.uz)) {
 +        /* find the portal on the new level */
 +        register struct trap *ttrap;
 +
 +        for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap)
 +        if (ttrap->ttyp == MAGIC_PORTAL) break;
 +
 +        if (!ttrap) panic("goto_level: no corresponding portal!");
 +        seetrap(ttrap);
 +        u_on_newpos(ttrap->tx, ttrap->ty);
 +    } else if (at_stairs && !In_endgame(&u.uz)) {
 +        if (up) {
 +        if (at_ladder)
 +            u_on_newpos(xdnladder, ydnladder);
 +        else if (newdungeon)
 +            u_on_sstairs(1);
 +        else
 +            u_on_dnstairs();
 +        /* you climb up the {stairs|ladder};
 +           fly up the stairs; fly up along the ladder */
 +        pline("%s %s up%s the %s.",
 +              (Punished && !Levitation) ? "With great effort you" :
 +                          "You",
 +              Flying ? "fly" : "climb",
 +              (Flying && at_ladder) ? " along" : "",
 +              at_ladder ? "ladder" : "stairs");
 +        } else {      /* down */
 +        if (at_ladder)
 +            u_on_newpos(xupladder, yupladder);
 +        else if (newdungeon)
 +            u_on_sstairs(0);
 +        else
 +            u_on_upstairs();
 +        if (!u.dz) {
 +            ; /* stayed on same level? (no transit effects) */
 +        } else if (Flying) {
 +            if (flags.verbose)
 +            You("fly down %s.",
 +                at_ladder ? "along the ladder" : "the stairs");
 +        } else if (near_capacity() > UNENCUMBERED ||
 +            Punished || Fumbling) {
 +            You("fall down the %s.", at_ladder ? "ladder" : "stairs");
 +            if (Punished) {
 +            drag_down();
 +            if (carried(uball)) {
 +                if (uwep == uball)
 +                setuwep((struct obj *)0);
 +                if (uswapwep == uball)
 +                setuswapwep((struct obj *)0);
 +                if (uquiver == uball)
 +                setuqwep((struct obj *)0);
 +                freeinv(uball);
 +            }
 +            }
 +            /* falling off steed has its own losehp() call */
 +            if (u.usteed)
 +            dismount_steed(DISMOUNT_FELL);
 +            else
 +            losehp(Maybe_Half_Phys(rnd(3)),
 +                   at_ladder ? "falling off a ladder" :
 +                       "tumbling down a flight of stairs",
 +                   KILLED_BY);
 +            selftouch("Falling, you");
 +        } else {      /* ordinary descent */
 +            if (flags.verbose)
 +            You("%s.", at_ladder ? "climb down the ladder" :
 +                           "descend the stairs");
 +        }
 +        }
 +    } else {  /* trap door or level_tele or In_endgame */
 +        u_on_rndspot((up ? 1 : 0) | (was_in_W_tower ? 2 : 0));
 +        if (falling) {
 +        if (Punished) ballfall();
 +        selftouch("Falling, you");
 +        }
 +    }
  
 -      if (Punished) placebc();
 -      obj_delivery(FALSE);
 -      losedogs();
 -      kill_genocided_monsters();  /* for those wiped out while in limbo */
 -      /*
 -       * Expire all timers that have gone off while away.  Must be
 -       * after migrating monsters and objects are delivered
 -       * (losedogs and obj_delivery).
 -       */
 -      run_timers();
 -
 -      initrack();
 -
 -      if ((mtmp = m_at(u.ux, u.uy)) != 0 && mtmp != u.usteed) {
 -          /* There's a monster at your target destination; it might be one
 -             which accompanied you--see mon_arrive(dogmove.c)--or perhaps
 -             it was already here.  Randomly move you to an adjacent spot
 -             or else the monster to any nearby location.  Prior to 3.3.0
 -             the latter was done unconditionally. */
 -          coord cc;
 -
 -          if (!rn2(2) &&
 -                  enexto(&cc, u.ux, u.uy, youmonst.data) &&
 -                  distu(cc.x, cc.y) <= 2)
 -              u_on_newpos(cc.x, cc.y);        /*[maybe give message here?]*/
 -          else
 -              mnexto(mtmp);
 -
 -          if ((mtmp = m_at(u.ux, u.uy)) != 0) {
 -              /* there was an unconditional impossible("mnearto failed")
 -                 here, but it's not impossible and we're prepared to cope
 -                 with the situation, so only say something when debugging */
 -              if (wizard) pline("(monster in hero's way)");
 -              if (!rloc(mtmp, TRUE))
 -                  /* no room to move it; send it away, to return later */
 -                  migrate_to_level(mtmp, ledger_no(&u.uz),
 -                                   MIGR_RANDOM, (coord *)0);
 -          }
 -      }
 +    if (Punished) placebc();
 +    obj_delivery(FALSE);
 +    losedogs();
 +    kill_genocided_monsters();  /* for those wiped out while in limbo */
 +    /*
 +     * Expire all timers that have gone off while away.  Must be
 +     * after migrating monsters and objects are delivered
 +     * (losedogs and obj_delivery).
 +     */
 +    run_timers();
 +
 +    initrack();
 +
 +    if ((mtmp = m_at(u.ux, u.uy)) != 0 && mtmp != u.usteed) {
 +        /* There's a monster at your target destination; it might be one
 +           which accompanied you--see mon_arrive(dogmove.c)--or perhaps
 +           it was already here.  Randomly move you to an adjacent spot
 +           or else the monster to any nearby location.  Prior to 3.3.0
 +           the latter was done unconditionally. */
 +        coord cc;
 +
 +        if (!rn2(2) &&
 +            enexto(&cc, u.ux, u.uy, youmonst.data) &&
 +            distu(cc.x, cc.y) <= 2)
 +        u_on_newpos(cc.x, cc.y);      /*[maybe give message here?]*/
 +        else
 +        mnexto(mtmp);
 +
 +        if ((mtmp = m_at(u.ux, u.uy)) != 0) {
 +        /* there was an unconditional impossible("mnearto failed")
 +           here, but it's not impossible and we're prepared to cope
 +           with the situation, so only say something when debugging */
 +        if (wizard) pline("(monster in hero's way)");
 +        if (!rloc(mtmp, TRUE))
 +            /* no room to move it; send it away, to return later */
 +            migrate_to_level(mtmp, ledger_no(&u.uz),
 +                     MIGR_RANDOM, (coord *)0);
 +        }
 +    }
  
 -      /* initial movement of bubbles just before vision_recalc */
 +    /* initial movement of bubbles just before vision_recalc */
-     if (Is_waterlevel(&u.uz))
+       if (Is_waterlevel(&u.uz) || Is_airlevel(&u.uz))
 -              movebubbles();
 +        movebubbles();
  
 -      if (level_info[new_ledger].flags & FORGOTTEN) {
 -          forget_map(ALL_MAP);        /* forget the map */
 -          forget_traps();             /* forget all traps too */
 -          familiar = TRUE;
 -          level_info[new_ledger].flags &= ~FORGOTTEN;
 -      }
 +    if (level_info[new_ledger].flags & FORGOTTEN) {
 +        forget_map(ALL_MAP);  /* forget the map */
 +        forget_traps();               /* forget all traps too */
 +        familiar = TRUE;
 +        level_info[new_ledger].flags &= ~FORGOTTEN;
 +    }
  
 -      /* Reset the screen. */
 -      vision_reset();         /* reset the blockages */
 -      docrt();                /* does a full vision recalc */
 -      flush_screen(-1);
 +    /* Reset the screen. */
 +    vision_reset();           /* reset the blockages */
 +    docrt();          /* does a full vision recalc */
 +    flush_screen(-1);
  
 -      /*
 -       *  Move all plines beyond the screen reset.
 -       */
 +    /*
 +     *  Move all plines beyond the screen reset.
 +     */
  
 -      /* special levels can have a custom arrival message */
 -      deliver_splev_message();
 +    /* special levels can have a custom arrival message */
 +    deliver_splev_message();
  
 -      /* give room entrance message, if any */
 -      check_special_room(FALSE);
 +    /* give room entrance message, if any */
 +    check_special_room(FALSE);
  
 -      /* deliver objects traveling with player */
 -      obj_delivery(TRUE);
 +    /* deliver objects traveling with player */
 +    obj_delivery(TRUE);
  
 -      /* Check whether we just entered Gehennom. */
 -      if (!In_hell(&u.uz0) && Inhell) {
 -          if (Is_valley(&u.uz)) {
 -              You("arrive at the Valley of the Dead...");
 -              pline_The("odor of burnt flesh and decay pervades the air.");
 +    /* Check whether we just entered Gehennom. */
 +    if (!In_hell(&u.uz0) && Inhell) {
 +        if (Is_valley(&u.uz)) {
 +        You("arrive at the Valley of the Dead...");
 +        pline_The("odor of burnt flesh and decay pervades the air.");
  #ifdef MICRO
 -              display_nhwindow(WIN_MESSAGE, FALSE);
 +        display_nhwindow(WIN_MESSAGE, FALSE);
  #endif
 -              You_hear("groans and moans everywhere.");
 -          } else pline("It is hot here.  You smell smoke...");
 +        You_hear("groans and moans everywhere.");
 +        } else pline("It is hot here.  You smell smoke...");
            u.uachieve.enter_gehennom = 1;
 -      }
 -      /* in case we've managed to bypass the Valley's stairway down */
 -      if (Inhell && !Is_valley(&u.uz)) u.uevent.gehennom_entered = 1;
 -
 -      if (familiar) {
 -          static const char * const fam_msgs[4] = {
 -              "You have a sense of deja vu.",
 -              "You feel like you've been here before.",
 -              "This place %s familiar...",
 -              0       /* no message */
 -          };
 -          static const char * const halu_fam_msgs[4] = {
 -              "Whoa!  Everything %s different.",
 -              "You are surrounded by twisty little passages, all alike.",
 -              "Gee, this %s like uncle Conan's place...",
 -              0       /* no message */
 -          };
 -          const char *mesg;
 -          char buf[BUFSZ];
 -          int which = rn2(4);
 -
 -          if (Hallucination)
 -              mesg = halu_fam_msgs[which];
 -          else
 -              mesg = fam_msgs[which];
 -          if (mesg && index(mesg, '%')) {
 -              Sprintf(buf, mesg, !Blind ? "looks" : "seems");
 -              mesg = buf;
 -          }
 -          if (mesg) pline1(mesg);
 -      }
 +    }
 +    /* in case we've managed to bypass the Valley's stairway down */
 +    if (Inhell && !Is_valley(&u.uz)) u.uevent.gehennom_entered = 1;
 +
 +    if (familiar) {
 +        static const char * const fam_msgs[4] = {
 +        "You have a sense of deja vu.",
 +        "You feel like you've been here before.",
 +        "This place %s familiar...",
 +        0     /* no message */
 +        };
 +        static const char * const halu_fam_msgs[4] = {
 +        "Whoa!  Everything %s different.",
 +        "You are surrounded by twisty little passages, all alike.",
 +        "Gee, this %s like uncle Conan's place...",
 +        0     /* no message */
 +        };
 +        const char *mesg;
 +        char buf[BUFSZ];
 +        int which = rn2(4);
 +
 +        if (Hallucination)
 +        mesg = halu_fam_msgs[which];
 +        else
 +        mesg = fam_msgs[which];
 +        if (mesg && index(mesg, '%')) {
 +        Sprintf(buf, mesg, !Blind ? "looks" : "seems");
 +        mesg = buf;
 +        }
 +        if (mesg) pline1(mesg);
 +    }
  
 -      /* special location arrival messages/events */
 -      if (In_endgame(&u.uz)) {
 -          if (new && on_level(&u.uz, &astral_level))
 -              final_level();  /* guardian angel,&c */
 -          else if (newdungeon && u.uhave.amulet)
 -              resurrect();    /* force confrontation with Wizard */
 -      } else if (In_quest(&u.uz)) {
 -          onquest();          /* might be reaching locate|goal level */
 -      } else if (In_V_tower(&u.uz)) {
 -          if (newdungeon && In_hell(&u.uz0))
 -              pline_The("heat and smoke are gone.");
 -      } else if (Is_knox(&u.uz)) {
 -          /* alarm stops working once Croesus has died */
 -          if (new || !mvitals[PM_CROESUS].died) {
 -              You("have penetrated a high security area!");
 -              pline("An alarm sounds!");
 -              for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
 -                  if (DEADMONSTER(mtmp)) continue;
 -                  mtmp->msleeping = 0;
 -              }
 -          }
 -      } else {
 -          if (new && Is_rogue_level(&u.uz))
 -              You("enter what seems to be an older, more primitive world.");
 -          /* main dungeon message from your quest leader */
 -          if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") &&
 -                  !(u.uevent.qcompleted || u.uevent.qexpelled ||
 -                    quest_status.leader_is_dead)) {
 -              if (!u.uevent.qcalled) {
 -                  u.uevent.qcalled = 1;
 -                  com_pager(2);   /* main "leader needs help" message */
 -              } else {            /* reminder message */
 -                  com_pager(Role_if(PM_ROGUE) ? 4 : 3);
 -              }
 -          }
 -      }
 +    /* special location arrival messages/events */
 +    if (In_endgame(&u.uz)) {
 +        if (new && on_level(&u.uz, &astral_level))
 +        final_level();        /* guardian angel,&c */
 +        else if (newdungeon && u.uhave.amulet)
 +        resurrect();  /* force confrontation with Wizard */
 +    } else if (In_quest(&u.uz)) {
 +        onquest();            /* might be reaching locate|goal level */
 +    } else if (In_V_tower(&u.uz)) {
 +        if (newdungeon && In_hell(&u.uz0))
 +        pline_The("heat and smoke are gone.");
 +    } else if (Is_knox(&u.uz)) {
 +        /* alarm stops working once Croesus has died */
 +        if (new || !mvitals[PM_CROESUS].died) {
 +        You("have penetrated a high security area!");
 +        pline("An alarm sounds!");
 +        for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
 +            if (DEADMONSTER(mtmp)) continue;
 +            mtmp->msleeping = 0;
 +        }
 +        }
 +    } else {
 +        if (new && Is_rogue_level(&u.uz))
 +        You("enter what seems to be an older, more primitive world.");
 +        /* main dungeon message from your quest leader */
 +        if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") &&
 +            !(u.uevent.qcompleted || u.uevent.qexpelled ||
 +              quest_status.leader_is_dead)) {
 +        if (!u.uevent.qcalled) {
 +            u.uevent.qcalled = 1;
 +            com_pager(2);   /* main "leader needs help" message */
 +        } else {          /* reminder message */
 +            com_pager(Role_if(PM_ROGUE) ? 4 : 3);
 +        }
 +        }
 +    }
  
 -      assign_level(&u.uz0, &u.uz); /* reset u.uz0 */
 +    assign_level(&u.uz0, &u.uz); /* reset u.uz0 */
  #ifdef INSURANCE
 -      save_currentstate();
 +    save_currentstate();
  #endif
  
 -      /* assume this will always return TRUE when changing level */
 -      (void) in_out_region(u.ux, u.uy);
 -      (void) pickup(1);
 +    /* assume this will always return TRUE when changing level */
 +    (void) in_out_region(u.ux, u.uy);
 +    (void) pickup(1);
        context.polearm.hitmon = NULL;
  }
  
diff --cc src/files.c
index e80799ed1f1e43c2741f5fc003575e6b5c7bfcaf,179cd34377ebde655c44f4d286326d8f43eae6d7..02843bd1f77343d6ac3fefad26f17998a6af917b
@@@ -2164,304 -2166,307 +2164,307 @@@ int               src
  # endif /* MICRO */
  #endif /*NOCWD_ASSUMPTIONS*/
  
 -      } else if (match_varname(buf, "NAME", 4)) {
 -          (void) strncpy(plname, bufp, PL_NSIZ-1);
 -          plnamesuffix();
 -      } else if (match_varname(buf, "ROLE", 4) ||
 -                 match_varname(buf, "CHARACTER", 4)) {
 -          if ((len = str2role(bufp)) >= 0)
 -              flags.initrole = len;
 -      } else if (match_varname(buf, "DOGNAME", 3)) {
 -          (void) strncpy(dogname, bufp, PL_PSIZ-1);
 -      } else if (match_varname(buf, "CATNAME", 3)) {
 -          (void) strncpy(catname, bufp, PL_PSIZ-1);
 +    } else if (match_varname(buf, "NAME", 4)) {
 +        (void) strncpy(plname, bufp, PL_NSIZ-1);
 +        plnamesuffix();
 +    } else if (match_varname(buf, "ROLE", 4) ||
 +           match_varname(buf, "CHARACTER", 4)) {
 +        if ((len = str2role(bufp)) >= 0)
 +            flags.initrole = len;
 +    } else if (match_varname(buf, "DOGNAME", 3)) {
 +        (void) strncpy(dogname, bufp, PL_PSIZ-1);
 +    } else if (match_varname(buf, "CATNAME", 3)) {
 +        (void) strncpy(catname, bufp, PL_PSIZ-1);
  #ifdef SYSCF
 -      } else if (src == SET_IN_SYS && match_varname(buf, "WIZARDS", 7)) {
 -          if (sysopt.wizards) free(sysopt.wizards);
 -          sysopt.wizards = dupstr(bufp);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "SHELLERS", 8)) {
 -          if (sysopt.shellers) free(sysopt.shellers);
 -          sysopt.shellers = dupstr(bufp);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "WIZARDS", 7)) {
 +        if (sysopt.wizards) free(sysopt.wizards);
 +        sysopt.wizards = dupstr(bufp);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "SHELLERS", 8)) {
 +        if (sysopt.shellers) free(sysopt.shellers);
 +        sysopt.shellers = dupstr(bufp);
+       } else if (src == SET_IN_SYS && match_varname(buf, "EXPLORERS", 7)) {
+           if (sysopt.explorers) free(sysopt.explorers);
+           sysopt.explorers = dupstr(bufp);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "DEBUGFILES", 5)) {
 -          if (sysopt.debugfiles) free(sysopt.debugfiles);
 -          /* if showdebug() has already been called (perhaps we've added
 -             some debugpline() calls to option processing) and has found
 -             a value for getenv("DEBUGFILES"), don't override that */
 -          if (sysopt.env_dbgfl == 0)
 -              sysopt.debugfiles = dupstr(bufp);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) {
 -          if (sysopt.support) free(sysopt.support);
 -          sysopt.support = dupstr(bufp);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "RECOVER", 7)) {
 -          if (sysopt.recover) free(sysopt.recover);
 -          sysopt.recover = dupstr(bufp);
 -      } else if (match_varname(buf, "SEDUCE", 6)) {
 -          n = !!atoi(bufp);   /* XXX this could be tighter */
 -          /* allow anyone to turn it off, but only sysconf to turn it on*/
 -          if (src != SET_IN_SYS && n != 0) {
 -              raw_printf("Illegal value in SEDUCE");
 -              return 0;
 -          }
 -          sysopt.seduce = n;
 -          sysopt_seduce_set(sysopt.seduce);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "MAXPLAYERS", 10)) {
 -          n = atoi(bufp);
 -          /* XXX to get more than 25, need to rewrite all lock code */
 -          if (n < 1 || n > 25) {
 -              raw_printf("Illegal value in MAXPLAYERS (maximum is 25).");
 -              return 0;
 -          }
 -          sysopt.maxplayers = n;
 -      } else if (src == SET_IN_SYS && match_varname(buf, "PERSMAX", 7)) {
 -          n = atoi(bufp);
 -          if (n < 1) {
 -              raw_printf("Illegal value in PERSMAX (minimum is 1).");
 -              return 0;
 -          }
 -          sysopt.persmax = n;
 -      } else if (src == SET_IN_SYS && match_varname(buf, "PERS_IS_UID", 11)) {
 -          n = atoi(bufp);
 -          if (n != 0 && n != 1) {
 -              raw_printf("Illegal value in PERS_IS_UID (must be 0 or 1).");
 -              return 0;
 -          }
 -          sysopt.pers_is_uid = n;
 -      } else if (src == SET_IN_SYS && match_varname(buf, "ENTRYMAX", 8)) {
 -          n = atoi(bufp);
 -          if (n < 10) {
 -              raw_printf("Illegal value in ENTRYMAX (minimum is 10).");
 -              return 0;
 -          }
 -          sysopt.entrymax = n;
 -      } else if ( (src==SET_IN_SYS) && match_varname(buf, "POINTSMIN", 9)) {
 -          n = atoi(bufp);
 -          if (n < 1) {
 -              raw_printf("Illegal value in POINTSMIN (minimum is 1).");
 -              return 0;
 -          }
 -          sysopt.pointsmin = n;
 -      } else if (src == SET_IN_SYS && match_varname(buf, "MAX_STATUENAME_RANK", 10)) {
 -          n = atoi(bufp);
 -          if (n < 1) {
 -              raw_printf("Illegal value in MAX_STATUENAME_RANK (minimum is 1).");
 -              return 0;
 -          }
 -          sysopt.tt_oname_maxrank = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "DEBUGFILES", 5)) {
 +        if (sysopt.debugfiles) free(sysopt.debugfiles);
 +        /* if showdebug() has already been called (perhaps we've added
 +           some debugpline() calls to option processing) and has found
 +           a value for getenv("DEBUGFILES"), don't override that */
 +        if (sysopt.env_dbgfl == 0)
 +        sysopt.debugfiles = dupstr(bufp);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "SUPPORT", 7)) {
 +        if (sysopt.support) free(sysopt.support);
 +        sysopt.support = dupstr(bufp);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "RECOVER", 7)) {
 +        if (sysopt.recover) free(sysopt.recover);
 +        sysopt.recover = dupstr(bufp);
 +    } else if (match_varname(buf, "SEDUCE", 6)) {
 +        n = !!atoi(bufp);     /* XXX this could be tighter */
 +        /* allow anyone to turn it off, but only sysconf to turn it on*/
 +        if (src != SET_IN_SYS && n != 0) {
 +        raw_printf("Illegal value in SEDUCE");
 +        return 0;
 +        }
 +        sysopt.seduce = n;
 +        sysopt_seduce_set(sysopt.seduce);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "MAXPLAYERS", 10)) {
 +        n = atoi(bufp);
 +        /* XXX to get more than 25, need to rewrite all lock code */
 +        if (n < 1 || n > 25) {
 +        raw_printf("Illegal value in MAXPLAYERS (maximum is 25).");
 +        return 0;
 +        }
 +        sysopt.maxplayers = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "PERSMAX", 7)) {
 +        n = atoi(bufp);
 +        if (n < 1) {
 +        raw_printf("Illegal value in PERSMAX (minimum is 1).");
 +        return 0;
 +        }
 +        sysopt.persmax = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "PERS_IS_UID", 11)) {
 +        n = atoi(bufp);
 +        if (n != 0 && n != 1) {
 +        raw_printf("Illegal value in PERS_IS_UID (must be 0 or 1).");
 +        return 0;
 +        }
 +        sysopt.pers_is_uid = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "ENTRYMAX", 8)) {
 +        n = atoi(bufp);
 +        if (n < 10) {
 +        raw_printf("Illegal value in ENTRYMAX (minimum is 10).");
 +        return 0;
 +        }
 +        sysopt.entrymax = n;
 +    } else if ( (src==SET_IN_SYS) && match_varname(buf, "POINTSMIN", 9)) {
 +        n = atoi(bufp);
 +        if (n < 1) {
 +        raw_printf("Illegal value in POINTSMIN (minimum is 1).");
 +        return 0;
 +        }
 +        sysopt.pointsmin = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "MAX_STATUENAME_RANK", 10)) {
 +        n = atoi(bufp);
 +        if (n < 1) {
 +        raw_printf("Illegal value in MAX_STATUENAME_RANK (minimum is 1).");
 +        return 0;
 +        }
 +        sysopt.tt_oname_maxrank = n;
  # ifdef PANICTRACE
 -      } else if (src == SET_IN_SYS &&
 -              match_varname(buf, "PANICTRACE_LIBC", 15)) {
 +    } else if (src == SET_IN_SYS &&
 +        match_varname(buf, "PANICTRACE_LIBC", 15)) {
  #  ifdef PANICTRACE_LIBC
 -          n = atoi(bufp);
 -          if (n < 0 || n > 2) {
 -              raw_printf("Illegal value in PANICTRACE_LIBC (not 0,1,2).");
 -              return 0;
 -          }
 -          sysopt.panictrace_libc = n;
 +        n = atoi(bufp);
 +        if (n < 0 || n > 2) {
 +        raw_printf("Illegal value in PANICTRACE_LIBC (not 0,1,2).");
 +        return 0;
 +        }
 +        sysopt.panictrace_libc = n;
  #  endif /* PANICTRACE_LIBC */
 -      } else if (src == SET_IN_SYS &&
 -              match_varname(buf, "PANICTRACE_GDB", 14)) {
 -          n = atoi(bufp);
 -          if (n < 0 || n > 2) {
 -              raw_printf("Illegal value in PANICTRACE_GDB (not 0,1,2).");
 -              return 0;
 -          }
 -          sysopt.panictrace_gdb = n;
 -      } else if (src == SET_IN_SYS && match_varname(buf, "GDBPATH", 7)) {
 -          if (!file_exists(bufp)) {
 -              raw_printf("File specified in GDBPATH does not exist.");
 -              return 0;
 -          }
 -          if (sysopt.gdbpath) free(sysopt.gdbpath);
 -          sysopt.gdbpath = dupstr(bufp);
 -      } else if (src == SET_IN_SYS && match_varname(buf, "GREPPATH", 7)) {
 -          if (!file_exists(bufp)) {
 -              raw_printf("File specified in GREPPATH does not exist.");
 -              return 0;
 -          }
 -          if (sysopt.greppath) free(sysopt.greppath);
 -          sysopt.greppath = dupstr(bufp);
 +    } else if (src == SET_IN_SYS &&
 +        match_varname(buf, "PANICTRACE_GDB", 14)) {
 +        n = atoi(bufp);
 +        if (n < 0 || n > 2) {
 +        raw_printf("Illegal value in PANICTRACE_GDB (not 0,1,2).");
 +        return 0;
 +        }
 +        sysopt.panictrace_gdb = n;
 +    } else if (src == SET_IN_SYS && match_varname(buf, "GDBPATH", 7)) {
 +        if (!file_exists(bufp)) {
 +        raw_printf("File specified in GDBPATH does not exist.");
 +        return 0;
 +        }
 +        if (sysopt.gdbpath) free(sysopt.gdbpath);
 +        sysopt.gdbpath = dupstr(bufp);
 +    } else if (src == SET_IN_SYS && match_varname(buf, "GREPPATH", 7)) {
 +        if (!file_exists(bufp)) {
 +        raw_printf("File specified in GREPPATH does not exist.");
 +        return 0;
 +        }
 +        if (sysopt.greppath) free(sysopt.greppath);
 +        sysopt.greppath = dupstr(bufp);
  # endif /* PANICTRACE */
  #endif /* SYSCF */
 -      } else if (match_varname(buf, "BOULDER", 3)) {
 -          (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
 -                            1, "BOULDER");
 -      } else if (match_varname(buf, "WARNINGS", 5)) {
 -          (void) get_uchars(fp, buf, bufp, translate, FALSE,
 -                                      WARNCOUNT, "WARNINGS");
 -          assign_warnings(translate);
 -      } else if (match_varname(buf, "SYMBOLS", 4)) {
 -              char *op, symbuf[BUFSZ];
 -              boolean morelines;
 -              do {
 -                      morelines = FALSE;
 -
 -                      /* strip leading and trailing white space */
 -                      while (isspace(*bufp)) bufp++;
 -                      op = eos(bufp);
 -                      while (--op >= bufp && isspace(*op)) *op = '\0';
 -
 -                      /* check for line continuation (trailing '\') */
 -                      op = eos(bufp);
 -                      if (--op >= bufp && *op == '\\') {
 -                          *op = '\0';
 -                          morelines = TRUE;
 -                          /* strip trailing space now that '\' is gone */
 -                          while (--op >= bufp && isspace(*op)) *op = '\0';
 -                      }
 -                      /* parse here */
 -                      parsesymbols(bufp);     
 -                      if (morelines)
 -                        do  {
 -                          *symbuf = '\0';
 -                          if (!fgets(symbuf, BUFSZ, fp)) {
 -                                      morelines = FALSE;
 -                                      break;
 -                          }
 -                          bufp = symbuf;
 -                      } while (*bufp == '#');
 -              } while (morelines);
 -              switch_symbols(TRUE);
 -      } else if (match_varname(buf, "WIZKIT", 6)) {
 -          (void) strncpy(wizkit, bufp, WIZKIT_MAX-1);
 +    } else if (match_varname(buf, "BOULDER", 3)) {
 +        (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
 +                  1, "BOULDER");
 +    } else if (match_varname(buf, "WARNINGS", 5)) {
 +        (void) get_uchars(fp, buf, bufp, translate, FALSE,
 +                    WARNCOUNT, "WARNINGS");
 +        assign_warnings(translate);
 +    } else if (match_varname(buf, "SYMBOLS", 4)) {
 +        char *op, symbuf[BUFSZ];
 +        boolean morelines;
 +        do {
 +            morelines = FALSE;
 +
 +            /* strip leading and trailing white space */
 +            while (isspace(*bufp)) bufp++;
 +            op = eos(bufp);
 +            while (--op >= bufp && isspace(*op)) *op = '\0';
 +
 +            /* check for line continuation (trailing '\') */
 +            op = eos(bufp);
 +            if (--op >= bufp && *op == '\\') {
 +                *op = '\0';
 +                morelines = TRUE;
 +                /* strip trailing space now that '\' is gone */
 +                while (--op >= bufp && isspace(*op)) *op = '\0';
 +            }
 +            /* parse here */
 +            parsesymbols(bufp);       
 +            if (morelines)
 +              do  {
 +                *symbuf = '\0';
 +                if (!fgets(symbuf, BUFSZ, fp)) {
 +                    morelines = FALSE;
 +                    break;
 +                }
 +                bufp = symbuf;
 +            } while (*bufp == '#');
 +        } while (morelines);
 +        switch_symbols(TRUE);
 +    } else if (match_varname(buf, "WIZKIT", 6)) {
 +        (void) strncpy(wizkit, bufp, WIZKIT_MAX-1);
  #ifdef AMIGA
 -      } else if (match_varname(buf, "FONT", 4)) {
 -              char *t;
 -
 -              if( t = strchr( buf+5, ':' ) )
 -              {
 -                  *t = 0;
 -                  amii_set_text_font( buf+5, atoi( t + 1 ) );
 -                  *t = ':';
 -              }
 -      } else if (match_varname(buf, "PATH", 4)) {
 -              (void) strncpy(PATH, bufp, PATHLEN-1);
 -      } else if (match_varname(buf, "DEPTH", 5)) {
 -              extern int amii_numcolors;
 -              int val = atoi( bufp );
 -              amii_numcolors = 1L << min( DEPTH, val );
 +    } else if (match_varname(buf, "FONT", 4)) {
 +        char *t;
 +
 +        if( t = strchr( buf+5, ':' ) )
 +        {
 +            *t = 0;
 +            amii_set_text_font( buf+5, atoi( t + 1 ) );
 +            *t = ':';
 +        }
 +    } else if (match_varname(buf, "PATH", 4)) {
 +        (void) strncpy(PATH, bufp, PATHLEN-1);
 +    } else if (match_varname(buf, "DEPTH", 5)) {
 +        extern int amii_numcolors;
 +        int val = atoi( bufp );
 +        amii_numcolors = 1L << min( DEPTH, val );
  #if defined(SYSFLAGS)
 -      } else if (match_varname(buf, "DRIPENS", 7)) {
 -              int i, val;
 -              char *t;
 -              for (i = 0, t = strtok(bufp, ",/"); t != (char *)0;
 -                              i < 20 && (t = strtok((char*)0, ",/")), ++i) {
 -                      sscanf(t, "%d", &val );
 -                      sysflags.amii_dripens[i] = val;
 -              }
 -#endif
 -      } else if (match_varname(buf, "SCREENMODE", 10 )) {
 -              extern long amii_scrnmode;
 -              if (!stricmp(bufp,"req"))
 -                  amii_scrnmode = 0xffffffff; /* Requester */
 -              else if( sscanf(bufp, "%x", &amii_scrnmode) != 1 )
 -                  amii_scrnmode = 0;
 -      } else if (match_varname(buf, "MSGPENS", 7)) {
 -              extern int amii_msgAPen, amii_msgBPen;
 -              char *t = strtok(bufp, ",/");
 -              if( t )
 -              {
 -                  sscanf(t, "%d", &amii_msgAPen);
 -                  if( t = strtok((char*)0, ",/") )
 -                              sscanf(t, "%d", &amii_msgBPen);
 -              }
 -      } else if (match_varname(buf, "TEXTPENS", 8)) {
 -              extern int amii_textAPen, amii_textBPen;
 -              char *t = strtok(bufp, ",/");
 -              if( t )
 -              {
 -                  sscanf(t, "%d", &amii_textAPen);
 -                  if( t = strtok((char*)0, ",/") )
 -                              sscanf(t, "%d", &amii_textBPen);
 -              }
 -      } else if (match_varname(buf, "MENUPENS", 8)) {
 -              extern int amii_menuAPen, amii_menuBPen;
 -              char *t = strtok(bufp, ",/");
 -              if( t )
 -              {
 -                  sscanf(t, "%d", &amii_menuAPen);
 -                  if( t = strtok((char*)0, ",/") )
 -                              sscanf(t, "%d", &amii_menuBPen);
 -              }
 -      } else if (match_varname(buf, "STATUSPENS", 10)) {
 -              extern int amii_statAPen, amii_statBPen;
 -              char *t = strtok(bufp, ",/");
 -              if( t )
 -              {
 -                  sscanf(t, "%d", &amii_statAPen);
 -                  if( t = strtok((char*)0, ",/") )
 -                              sscanf(t, "%d", &amii_statBPen);
 -              }
 -      } else if (match_varname(buf, "OTHERPENS", 9)) {
 -              extern int amii_otherAPen, amii_otherBPen;
 -              char *t = strtok(bufp, ",/");
 -              if( t )
 -              {
 -                  sscanf(t, "%d", &amii_otherAPen);
 -                  if( t = strtok((char*)0, ",/") )
 -                              sscanf(t, "%d", &amii_otherBPen);
 -              }
 -      } else if (match_varname(buf, "PENS", 4)) {
 -              extern unsigned short amii_init_map[ AMII_MAXCOLORS ];
 -              int i;
 -              char *t;
 -
 -              for (i = 0, t = strtok(bufp, ",/");
 -                      i < AMII_MAXCOLORS && t != (char *)0;
 -                      t = strtok((char *)0, ",/"), ++i)
 -              {
 -                      sscanf(t, "%hx", &amii_init_map[i]);
 -              }
 -              amii_setpens( amii_numcolors = i );
 -      } else if (match_varname(buf, "FGPENS", 6)) {
 -              extern int foreg[ AMII_MAXCOLORS ];
 -              int i;
 -              char *t;
 -
 -              for (i = 0, t = strtok(bufp, ",/");
 -                      i < AMII_MAXCOLORS && t != (char *)0;
 -                      t = strtok((char *)0, ",/"), ++i)
 -              {
 -                      sscanf(t, "%d", &foreg[i]);
 -              }
 -      } else if (match_varname(buf, "BGPENS", 6)) {
 -              extern int backg[ AMII_MAXCOLORS ];
 -              int i;
 -              char *t;
 -
 -              for (i = 0, t = strtok(bufp, ",/");
 -                      i < AMII_MAXCOLORS && t != (char *)0;
 -                      t = strtok((char *)0, ",/"), ++i)
 -              {
 -                      sscanf(t, "%d", &backg[i]);
 -              }
 +    } else if (match_varname(buf, "DRIPENS", 7)) {
 +        int i, val;
 +        char *t;
 +        for (i = 0, t = strtok(bufp, ",/"); t != (char *)0;
 +                i < 20 && (t = strtok((char*)0, ",/")), ++i) {
 +            sscanf(t, "%d", &val );
 +            sysflags.amii_dripens[i] = val;
 +        }
 +#endif
 +    } else if (match_varname(buf, "SCREENMODE", 10 )) {
 +        extern long amii_scrnmode;
 +        if (!stricmp(bufp,"req"))
 +            amii_scrnmode = 0xffffffff; /* Requester */
 +        else if( sscanf(bufp, "%x", &amii_scrnmode) != 1 )
 +            amii_scrnmode = 0;
 +    } else if (match_varname(buf, "MSGPENS", 7)) {
 +        extern int amii_msgAPen, amii_msgBPen;
 +        char *t = strtok(bufp, ",/");
 +        if( t )
 +        {
 +            sscanf(t, "%d", &amii_msgAPen);
 +            if( t = strtok((char*)0, ",/") )
 +                sscanf(t, "%d", &amii_msgBPen);
 +        }
 +    } else if (match_varname(buf, "TEXTPENS", 8)) {
 +        extern int amii_textAPen, amii_textBPen;
 +        char *t = strtok(bufp, ",/");
 +        if( t )
 +        {
 +            sscanf(t, "%d", &amii_textAPen);
 +            if( t = strtok((char*)0, ",/") )
 +                sscanf(t, "%d", &amii_textBPen);
 +        }
 +    } else if (match_varname(buf, "MENUPENS", 8)) {
 +        extern int amii_menuAPen, amii_menuBPen;
 +        char *t = strtok(bufp, ",/");
 +        if( t )
 +        {
 +            sscanf(t, "%d", &amii_menuAPen);
 +            if( t = strtok((char*)0, ",/") )
 +                sscanf(t, "%d", &amii_menuBPen);
 +        }
 +    } else if (match_varname(buf, "STATUSPENS", 10)) {
 +        extern int amii_statAPen, amii_statBPen;
 +        char *t = strtok(bufp, ",/");
 +        if( t )
 +        {
 +            sscanf(t, "%d", &amii_statAPen);
 +            if( t = strtok((char*)0, ",/") )
 +                sscanf(t, "%d", &amii_statBPen);
 +        }
 +    } else if (match_varname(buf, "OTHERPENS", 9)) {
 +        extern int amii_otherAPen, amii_otherBPen;
 +        char *t = strtok(bufp, ",/");
 +        if( t )
 +        {
 +            sscanf(t, "%d", &amii_otherAPen);
 +            if( t = strtok((char*)0, ",/") )
 +                sscanf(t, "%d", &amii_otherBPen);
 +        }
 +    } else if (match_varname(buf, "PENS", 4)) {
 +        extern unsigned short amii_init_map[ AMII_MAXCOLORS ];
 +        int i;
 +        char *t;
 +
 +        for (i = 0, t = strtok(bufp, ",/");
 +            i < AMII_MAXCOLORS && t != (char *)0;
 +            t = strtok((char *)0, ",/"), ++i)
 +        {
 +            sscanf(t, "%hx", &amii_init_map[i]);
 +        }
 +        amii_setpens( amii_numcolors = i );
 +    } else if (match_varname(buf, "FGPENS", 6)) {
 +        extern int foreg[ AMII_MAXCOLORS ];
 +        int i;
 +        char *t;
 +
 +        for (i = 0, t = strtok(bufp, ",/");
 +            i < AMII_MAXCOLORS && t != (char *)0;
 +            t = strtok((char *)0, ",/"), ++i)
 +        {
 +            sscanf(t, "%d", &foreg[i]);
 +        }
 +    } else if (match_varname(buf, "BGPENS", 6)) {
 +        extern int backg[ AMII_MAXCOLORS ];
 +        int i;
 +        char *t;
 +
 +        for (i = 0, t = strtok(bufp, ",/");
 +            i < AMII_MAXCOLORS && t != (char *)0;
 +            t = strtok((char *)0, ",/"), ++i)
 +        {
 +            sscanf(t, "%d", &backg[i]);
 +        }
  #endif
  #ifdef USER_SOUNDS
 -      } else if (match_varname(buf, "SOUNDDIR", 8)) {
 -              sounddir = dupstr(bufp);
 -      } else if (match_varname(buf, "SOUND", 5)) {
 -              add_sound_mapping(bufp);
 +    } else if (match_varname(buf, "SOUNDDIR", 8)) {
 +        sounddir = dupstr(bufp);
 +    } else if (match_varname(buf, "SOUND", 5)) {
 +        add_sound_mapping(bufp);
  #endif
  #ifdef QT_GRAPHICS
 -      /* These should move to wc_ options */
 -      } else if (match_varname(buf, "QT_TILEWIDTH", 12)) {
 -              extern char *qt_tilewidth;
 -              if (qt_tilewidth == NULL)       
 -                      qt_tilewidth = dupstr(bufp);
 -      } else if (match_varname(buf, "QT_TILEHEIGHT", 13)) {
 -              extern char *qt_tileheight;
 -              if (qt_tileheight == NULL)      
 -                      qt_tileheight = dupstr(bufp);
 -      } else if (match_varname(buf, "QT_FONTSIZE", 11)) {
 -              extern char *qt_fontsize;
 -              if (qt_fontsize == NULL)
 -                      qt_fontsize = dupstr(bufp);
 -      } else if (match_varname(buf, "QT_COMPACT", 10)) {
 -              extern int qt_compact_mode;
 -              qt_compact_mode = atoi(bufp);
 -#endif
 -      } else
 -              return 0;
 -      return 1;
 +    /* These should move to wc_ options */
 +    } else if (match_varname(buf, "QT_TILEWIDTH", 12)) {
 +        extern char *qt_tilewidth;
 +        if (qt_tilewidth == NULL)     
 +            qt_tilewidth = dupstr(bufp);
 +    } else if (match_varname(buf, "QT_TILEHEIGHT", 13)) {
 +        extern char *qt_tileheight;
 +        if (qt_tileheight == NULL)    
 +            qt_tileheight = dupstr(bufp);
 +    } else if (match_varname(buf, "QT_FONTSIZE", 11)) {
 +        extern char *qt_fontsize;
 +        if (qt_fontsize == NULL)
 +            qt_fontsize = dupstr(bufp);
 +    } else if (match_varname(buf, "QT_COMPACT", 10)) {
 +        extern int qt_compact_mode;
 +        qt_compact_mode = atoi(bufp);
 +#endif
 +    } else
 +        return 0;
 +    return 1;
  }
  
  #ifdef USER_SOUNDS
diff --cc src/hack.c
index ef8c90a52de5ddafac5fa23b7372767e12ae482a,5e14a3fabaf52599a7153d26068b21232b3fe2e6..ebf1ce891f624a25396e35c0ede6e4c3844854e9
@@@ -1101,491 -1101,491 +1101,491 @@@ struct trap *desttrap;    /* nonnull if an
  void
  domove()
  {
 -      register struct monst *mtmp;
 -      register struct rm *tmpr;
 -      register xchar x,y;
 +    register struct monst *mtmp;
 +    register struct rm *tmpr;
 +    register xchar x,y;
-     struct trap *trap = NULL;
+       struct trap *trap = (struct trap *)0;
 -      int wtcap;
 -      boolean on_ice;
 -      xchar chainx, chainy, ballx, bally;     /* ball&chain new positions */
 -      int bc_control;                         /* control for ball&chain */
 -      boolean cause_delay = FALSE;    /* dragging ball will skip a move */
 -
 -      u_wipe_engr(rnd(5));
 -
 -      if (context.travel) {
 -          if (!findtravelpath(FALSE))
 -              (void) findtravelpath(TRUE);
 -          context.travel1 = 0;
 -      }
 -
 -      if(((wtcap = near_capacity()) >= OVERLOADED
 -          || (wtcap > SLT_ENCUMBER &&
 -              (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
 -                      : (u.uhp < 10 && u.uhp != u.uhpmax))))
 -         && !Is_airlevel(&u.uz)) {
 -          if(wtcap < OVERLOADED) {
 -              You("don't have enough stamina to move.");
 -              exercise(A_CON, FALSE);
 -          } else
 -              You("collapse under your load.");
 -          nomul(0);
 -          return;
 -      }
 -      if(u.uswallow) {
 -              u.dx = u.dy = 0;
 -              u.ux = x = u.ustuck->mx;
 -              u.uy = y = u.ustuck->my;
 -              mtmp = u.ustuck;
 -      } else {
 -              if (Is_airlevel(&u.uz) && rn2(4) &&
 -                      !Levitation && !Flying) {
 -                  switch(rn2(3)) {
 -                  case 0:
 -                      You("tumble in place.");
 -                      exercise(A_DEX, FALSE);
 -                      break;
 -                  case 1:
 -                      You_cant("control your movements very well."); break;
 -                  case 2:
 -                      pline("It's hard to walk in thin air.");
 -                      exercise(A_DEX, TRUE);
 -                      break;
 -                  }
 -                  return;
 -              }
 -
 -              /* check slippery ice */
 -              on_ice = !Levitation && is_ice(u.ux, u.uy);
 -              if (on_ice) {
 -                  static int skates = 0;
 -                  if (!skates) skates = find_skates();
 -                  if ((uarmf && uarmf->otyp == skates)
 -                          || resists_cold(&youmonst) || Flying
 -                          || is_floater(youmonst.data) || is_clinger(youmonst.data)
 -                          || is_whirly(youmonst.data))
 -                      on_ice = FALSE;
 -                  else if (!rn2(Cold_resistance ? 3 : 2)) {
 -                      HFumbling |= FROMOUTSIDE;
 -                      HFumbling &= ~TIMEOUT;
 -                      HFumbling += 1;  /* slip on next move */
 -                  }
 -              }
 -              if (!on_ice && (HFumbling & FROMOUTSIDE))
 -                  HFumbling &= ~FROMOUTSIDE;
 -
 -              x = u.ux + u.dx;
 -              y = u.uy + u.dy;
 -              if(Stunned || (Confusion && !rn2(5))) {
 -                      register int tries = 0;
 -
 -                      do {
 -                              if(tries++ > 50) {
 -                                      nomul(0);
 -                                      return;
 -                              }
 -                              confdir();
 -                              x = u.ux + u.dx;
 -                              y = u.uy + u.dy;
 -                      } while(!isok(x, y) || bad_rock(youmonst.data, x, y));
 -              }
 -              /* turbulence might alter your actual destination */
 -              if (u.uinwater) {
 -                      water_friction();
 -                      if (!u.dx && !u.dy) {
 -                              nomul(0);
 -                              return;
 -                      }
 -                      x = u.ux + u.dx;
 -                      y = u.uy + u.dy;
 -              }
 -              if(!isok(x, y)) {
 -                      nomul(0);
 -                      return;
 -              }
 -              if (((trap = t_at(x, y)) && trap->tseen) ||
 -                  (Blind && !Levitation && !Flying &&
 -                   !is_clinger(youmonst.data) &&
 -                   is_pool_or_lava(x, y) && levl[x][y].seenv)) {
 -                      if(context.run >= 2) {
 -                              nomul(0);
 -                              context.move = 0;
 -                              return;
 -                      } else
 -                              nomul(0);
 -              }
 -
 -              if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
 -                  if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
 -                      /* perhaps it fled (or was teleported or ... ) */
 -                      u.ustuck = 0;
 -                  } else if (sticks(youmonst.data)) {
 -                      /* When polymorphed into a sticking monster,
 -                       * u.ustuck means it's stuck to you, not you to it.
 -                       */
 -                      You("release %s.", mon_nam(u.ustuck));
 -                      u.ustuck = 0;
 -                  } else {
 -                      /* If holder is asleep or paralyzed:
 -                       *      37.5% chance of getting away,
 -                       *      12.5% chance of waking/releasing it;
 -                       * otherwise:
 -                       *       7.5% chance of getting away.
 -                       * [strength ought to be a factor]
 -                       * If holder is tame and there is no conflict,
 -                       * guaranteed escape.
 -                       */
 -                      switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
 -                      case 0: case 1: case 2:
 -                      pull_free:
 -                          You("pull free from %s.", mon_nam(u.ustuck));
 -                          u.ustuck = 0;
 -                          break;
 -                      case 3:
 -                          if (!u.ustuck->mcanmove) {
 -                              /* it's free to move on next turn */
 -                              u.ustuck->mfrozen = 1;
 -                              u.ustuck->msleeping = 0;
 -                          }
 -                          /*FALLTHRU*/
 -                      default:
 -                          if (u.ustuck->mtame &&
 -                              !Conflict && !u.ustuck->mconf)
 -                              goto pull_free;
 -                          You("cannot escape from %s!", mon_nam(u.ustuck));
 -                          nomul(0);
 -                          return;
 -                      }
 -                  }
 -              }
 -
 -              mtmp = m_at(x,y);
 -              if (mtmp) {
 -                      /* Don't attack if you're running, and can see it */
 -                      /* We should never get here if forcefight */
 -                      if (context.run &&
 -                          ((!Blind && mon_visible(mtmp) &&
 -                            ((mtmp->m_ap_type != M_AP_FURNITURE &&
 -                              mtmp->m_ap_type != M_AP_OBJECT) ||
 -                             Protection_from_shape_changers)) ||
 -                           sensemon(mtmp))) {
 -                              nomul(0);
 -                              context.move = 0;
 -                              return;
 -                      }
 -              }
 -      }
 -
 -      u.ux0 = u.ux;
 -      u.uy0 = u.uy;
 -      bhitpos.x = x;
 -      bhitpos.y = y;
 -      tmpr = &levl[x][y];
 -
 -      /* attack monster */
 -      if(mtmp) {
 -          nomul(0);
 -          /* only attack if we know it's there */
 -          /* or if we used the 'F' command to fight blindly */
 -          /* or if it hides_under, in which case we call attack() to print
 -           * the Wait! message.
 -           * This is different from ceiling hiders, who aren't handled in
 -           * attack().
 -           */
 -
 -          /* If they used a 'm' command, trying to move onto a monster
 -           * prints the below message and wastes a turn.  The exception is
 -           * if the monster is unseen and the player doesn't remember an
 -           * invisible monster--then, we fall through to attack() and
 -           * attack_check(), which still wastes a turn, but prints a
 -           * different message and makes the player remember the monster.                  */
 -          if(context.nopick &&
 -                (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){
 -              if(mtmp->m_ap_type && !Protection_from_shape_changers
 -                                                  && !sensemon(mtmp))
 -                  stumble_onto_mimic(mtmp);
 -              else if (mtmp->mpeaceful && !Hallucination)
 -                  pline("Pardon me, %s.", m_monnam(mtmp));
 -              else
 -                  You("move right into %s.", mon_nam(mtmp));
 -              return;
 -          }
 -          if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
 -                  ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
 -                      !is_safepet(mtmp))){
 -              /* try to attack; note that it might evade */
 -              /* also, we don't attack tame when _safepet_ */
 -              if(attack(mtmp)) return;
 -          }
 -      }
 -
 -      /* specifying 'F' with no monster wastes a turn */
 -      if (context.forcefight ||
 -          /* remembered an 'I' && didn't use a move command */
 -          (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
 -              struct obj *boulder = sobj_at(BOULDER, x, y);
 -              boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
 -                      solid = !accessible(x, y);
 -              int glyph = glyph_at(x, y);     /* might be monster */
 -              char buf[BUFSZ];
 -
 -              /* if a statue is displayed at the target location,
 -                 player is attempting to attack it [and boulder
 -                 handlng below is suitable for handling that] */
 -              if (glyph_is_statue(glyph) ||
 -                      (Hallucination && glyph_is_monster(glyph)))
 -                  boulder = sobj_at(STATUE, x, y);
 -
 -              /* force fight at boulder/statue or wall/door while wielding
 -                 pick:  start digging to break the boulder or wall */
 -              if (context.forcefight &&
 -                      /* can we dig? */
 -                      uwep && dig_typ(uwep, x, y) &&
 -                      /* should we dig? */
 -                      !glyph_is_invisible(glyph) &&
 -                      !glyph_is_monster(glyph)) {
 -                  (void)use_pick_axe2(uwep);
 -                  return;
 -              }
 -
 -              if (boulder)
 -                  Strcpy(buf, ansimpleoname(boulder));
 -              else if (solid)
 -                  Strcpy(buf, the(defsyms[glyph_to_cmap(glyph)].explanation));
 -              else if (!Underwater)
 -                  Strcpy(buf, "thin air");
 -              else if (is_pool(x, y))
 -                  Strcpy(buf, "empty water");
 -              else    /* Underwater, targetting non-water */
 -                  Sprintf(buf, "a vacant spot on the %s", surface(x,y));
 -              You("%s%s %s.",
 -                  !(boulder || solid) ? "" :
 -                      !explo ? "harmlessly " : "futilely ",
 -                  explo ? "explode at" : "attack",
 -                  buf);
 -              unmap_object(x, y); /* known empty -- remove 'I' if present */
 -              if (boulder) map_object(boulder, TRUE);
 -              newsym(x, y);
 -              nomul(0);
 -              if (explo) {
 -                  wake_nearby();
 -                  u.mh = -1;          /* dead in the current form */
 -                  rehumanize();
 -              }
 -              return;
 -      }
 -      if (glyph_is_invisible(levl[x][y].glyph)) {
 -          unmap_object(x, y);
 -          newsym(x, y);
 -      }
 -      /* not attacking an animal, so we try to move */
 -      if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
 -              nomul(0);
 -              return;
 -      }
 -      if(!youmonst.data->mmove) {
 -              You("are rooted %s.",
 -                  Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
 -                  "in place" : "to the ground");
 -              nomul(0);
 -              return;
 -      }
 -      if(u.utrap) {
 -          if (!trapmove(x, y, trap)) return;
 -      }
 -
 -      if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) {
 -          context.move = 0;
 -          nomul(0);
 -          return;
 -      }
 -
 -      /* Move ball and chain.  */
 -      if (Punished)
 -          if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy,
 -                      &cause_delay, TRUE))
 -              return;
 -
 -      /* Check regions entering/leaving */
 -      if (!in_out_region(x,y))
 -          return;
 -
 -      /* now move the hero */
 -      mtmp = m_at(x, y);
 -      u.ux += u.dx;
 -      u.uy += u.dy;
 -      /* Move your steed, too */
 -      if (u.usteed) {
 -              u.usteed->mx = u.ux;
 -              u.usteed->my = u.uy;
 -              exercise_steed();
 -      }
 -
 -      /*
 -       * If safepet at destination then move the pet to the hero's
 -       * previous location using the same conditions as in attack().
 -       * there are special extenuating circumstances:
 -       * (1) if the pet dies then your god angers,
 -       * (2) if the pet gets trapped then your god may disapprove,
 -       * (3) if the pet was already trapped and you attempt to free it
 -       * not only do you encounter the trap but you may frighten your
 -       * pet causing it to go wild!  moral: don't abuse this privilege.
 -       *
 -       * Ceiling-hiding pets are skipped by this section of code, to
 -       * be caught by the normal falling-monster code.
 -       */
 -      if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
 -          /* if trapped, there's a chance the pet goes wild */
 -          if (mtmp->mtrapped) {
 -              if (!rn2(mtmp->mtame)) {
 -                  mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
 -                  if (mtmp->mleashed) m_unleash(mtmp, TRUE);
 -                  growl(mtmp);
 -              } else {
 -                  yelp(mtmp);
 -              }
 -          }
 -          mtmp->mundetected = 0;
 -          if (mtmp->m_ap_type) seemimic(mtmp);
 -          else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my);
 -
 -          if (mtmp->mtrapped &&
 -                  (trap = t_at(mtmp->mx, mtmp->my)) != 0 &&
 -                  (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&
 -                  sobj_at(BOULDER, trap->tx, trap->ty)) {
 -              /* can't swap places with pet pinned in a pit by a boulder */
 -              u.ux = u.ux0,  u.uy = u.uy0;    /* didn't move after all */
 -          } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
 -              /* can't swap places when pet can't move to your spot */
 -              u.ux = u.ux0,  u.uy = u.uy0;
 -              You("stop.  %s can't move diagonally.",
 -                  upstart(y_monnam(mtmp)));
 -          } else if (u.ux0 != x && u.uy0 != y &&
 -                     bad_rock(mtmp->data, x, u.uy0) &&
 -                     bad_rock(mtmp->data, u.ux0, y) &&
 -                     (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
 -              /* can't swap places when pet won't fit thru the opening */
 -              u.ux = u.ux0,  u.uy = u.uy0;    /* didn't move after all */
 -              You("stop.  %s won't fit through.", upstart(y_monnam(mtmp)));
 -          } else {
 -              char pnambuf[BUFSZ];
 -
 -              /* save its current description in case of polymorph */
 -              Strcpy(pnambuf, y_monnam(mtmp));
 -              mtmp->mtrapped = 0;
 -              remove_monster(x, y);
 -              place_monster(mtmp, u.ux0, u.uy0);
 -              newsym(x, y);
 -              newsym(u.ux0, u.uy0);
 -
 -              You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
 -                  pnambuf);
 -
 -              /* check for displacing it into pools and traps */
 -              switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
 -              case 0:
 -                  break;
 -              case 1:         /* trapped */
 -              case 3:         /* changed levels */
 -                  /* there's already been a trap message, reinforce it */
 -                  abuse_dog(mtmp);
 -                  adjalign(-3);
 -                  break;
 -              case 2:
 -                  /* drowned or died...
 -                   * you killed your pet by direct action, so get experience
 -                   * and possibly penalties;
 -                   * we want the level gain message, if it happens, to occur
 -                   * before the guilt message below
 -                   */
 -                {
 -                  /* minliquid() and mintrap() call mondead() rather than
 -                     killed() so we duplicate some of the latter here */
 -                  int tmp, mndx;
 -
 -                  u.uconduct.killer++;
 -                  mndx = monsndx(mtmp->data);
 -                  tmp = experience(mtmp, (int)mvitals[mndx].died);
 -                  more_experienced(tmp, 0);
 -                  newexplevel();      /* will decide if you go up */
 -                }
 -                  /* That's no way to treat a pet!  Your god gets angry.
 -                   *
 -                   * [This has always been pretty iffy.  Why does your
 -                   * patron deity care at all, let alone enough to get mad?]
 -                   */
 -                  if (rn2(4)) {
 -                      You_feel("guilty about losing your pet like this.");
 -                      u.ugangr++;
 -                      adjalign(-15);
 -                  }
 -                  break;
 -              default:
 -                  pline("that's strange, unknown mintrap result!");
 -                  break;
 -              }
 -          }
 -      }
 -
 -      reset_occupations();
 -      if (context.run) {
 -          if ( context.run < 8 )
 -              if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) ||
 -                      IS_FURNITURE(tmpr->typ))
 -                  nomul(0);
 -      }
 -
 -      if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) ||
 -          u.dx || u.dy)
 -          (void) hideunder(&youmonst);
 -
 -      /*
 -       * Mimics (or whatever) become noticeable if they move and are
 -       * imitating something that doesn't move.  We could extend this
 -       * to non-moving monsters...
 -       */
 -      if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT
 -                              || youmonst.m_ap_type == M_AP_FURNITURE))
 -          youmonst.m_ap_type = M_AP_NOTHING;
 -
 -      check_leash(u.ux0,u.uy0);
 -
 -      if(u.ux0 != u.ux || u.uy0 != u.uy) {
 -          u.umoved = TRUE;
 -          /* Clean old position -- vision_recalc() will print our new one. */
 -          newsym(u.ux0,u.uy0);
 -          /* Since the hero has moved, adjust what can be seen/unseen. */
 -          vision_recalc(1);   /* Do the work now in the recover time. */
 -          invocation_message();
 -      }
 -
 -      if (Punished)                           /* put back ball and chain */
 -          move_bc(0,bc_control,ballx,bally,chainx,chainy);
 -
 -      spoteffects(TRUE);
 -
 -      /* delay next move because of ball dragging */
 -      /* must come after we finished picking up, in spoteffects() */
 -      if (cause_delay) {
 -          nomul(-2);
 +    int wtcap;
 +    boolean on_ice;
 +    xchar chainx, chainy, ballx, bally;       /* ball&chain new positions */
 +    int bc_control;                           /* control for ball&chain */
 +    boolean cause_delay = FALSE;      /* dragging ball will skip a move */
 +
 +    u_wipe_engr(rnd(5));
 +
 +    if (context.travel) {
 +        if (!findtravelpath(FALSE))
 +        (void) findtravelpath(TRUE);
 +        context.travel1 = 0;
 +    }
 +
 +    if(((wtcap = near_capacity()) >= OVERLOADED
 +        || (wtcap > SLT_ENCUMBER &&
 +        (Upolyd ? (u.mh < 5 && u.mh != u.mhmax)
 +            : (u.uhp < 10 && u.uhp != u.uhpmax))))
 +       && !Is_airlevel(&u.uz)) {
 +        if(wtcap < OVERLOADED) {
 +        You("don't have enough stamina to move.");
 +        exercise(A_CON, FALSE);
 +        } else
 +        You("collapse under your load.");
 +        nomul(0);
 +        return;
 +    }
 +    if(u.uswallow) {
 +        u.dx = u.dy = 0;
 +        u.ux = x = u.ustuck->mx;
 +        u.uy = y = u.ustuck->my;
 +        mtmp = u.ustuck;
 +    } else {
 +        if (Is_airlevel(&u.uz) && rn2(4) &&
 +            !Levitation && !Flying) {
 +            switch(rn2(3)) {
 +            case 0:
 +            You("tumble in place.");
 +            exercise(A_DEX, FALSE);
 +            break;
 +            case 1:
 +            You_cant("control your movements very well."); break;
 +            case 2:
 +            pline("It's hard to walk in thin air.");
 +            exercise(A_DEX, TRUE);
 +            break;
 +            }
 +            return;
 +        }
 +
 +        /* check slippery ice */
 +        on_ice = !Levitation && is_ice(u.ux, u.uy);
 +        if (on_ice) {
 +            static int skates = 0;
 +            if (!skates) skates = find_skates();
 +            if ((uarmf && uarmf->otyp == skates)
 +                || resists_cold(&youmonst) || Flying
 +                || is_floater(youmonst.data) || is_clinger(youmonst.data)
 +                || is_whirly(youmonst.data))
 +            on_ice = FALSE;
 +            else if (!rn2(Cold_resistance ? 3 : 2)) {
 +            HFumbling |= FROMOUTSIDE;
 +            HFumbling &= ~TIMEOUT;
 +            HFumbling += 1;  /* slip on next move */
 +            }
 +        }
 +        if (!on_ice && (HFumbling & FROMOUTSIDE))
 +            HFumbling &= ~FROMOUTSIDE;
 +
 +        x = u.ux + u.dx;
 +        y = u.uy + u.dy;
 +        if(Stunned || (Confusion && !rn2(5))) {
 +            register int tries = 0;
 +
 +            do {
 +                if(tries++ > 50) {
 +                    nomul(0);
 +                    return;
 +                }
 +                confdir();
 +                x = u.ux + u.dx;
 +                y = u.uy + u.dy;
 +            } while(!isok(x, y) || bad_rock(youmonst.data, x, y));
 +        }
 +        /* turbulence might alter your actual destination */
 +        if (u.uinwater) {
 +            water_friction();
 +            if (!u.dx && !u.dy) {
 +                nomul(0);
 +                return;
 +            }
 +            x = u.ux + u.dx;
 +            y = u.uy + u.dy;
 +        }
 +        if(!isok(x, y)) {
 +            nomul(0);
 +            return;
 +        }
 +        if (((trap = t_at(x, y)) && trap->tseen) ||
 +            (Blind && !Levitation && !Flying &&
 +             !is_clinger(youmonst.data) &&
 +             is_pool_or_lava(x, y) && levl[x][y].seenv)) {
 +            if(context.run >= 2) {
 +                nomul(0);
 +                context.move = 0;
 +                return;
 +            } else
 +                nomul(0);
 +        }
 +
 +        if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) {
 +            if (distu(u.ustuck->mx, u.ustuck->my) > 2) {
 +            /* perhaps it fled (or was teleported or ... ) */
 +            u.ustuck = 0;
 +            } else if (sticks(youmonst.data)) {
 +            /* When polymorphed into a sticking monster,
 +             * u.ustuck means it's stuck to you, not you to it.
 +             */
 +            You("release %s.", mon_nam(u.ustuck));
 +            u.ustuck = 0;
 +            } else {
 +            /* If holder is asleep or paralyzed:
 +             *        37.5% chance of getting away,
 +             *        12.5% chance of waking/releasing it;
 +             * otherwise:
 +             *         7.5% chance of getting away.
 +             * [strength ought to be a factor]
 +             * If holder is tame and there is no conflict,
 +             * guaranteed escape.
 +             */
 +            switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) {
 +            case 0: case 1: case 2:
 +            pull_free:
 +                You("pull free from %s.", mon_nam(u.ustuck));
 +                u.ustuck = 0;
 +                break;
 +            case 3:
 +                if (!u.ustuck->mcanmove) {
 +                /* it's free to move on next turn */
 +                u.ustuck->mfrozen = 1;
 +                u.ustuck->msleeping = 0;
 +                }
 +                /*FALLTHRU*/
 +            default:
 +                if (u.ustuck->mtame &&
 +                !Conflict && !u.ustuck->mconf)
 +                goto pull_free;
 +                You("cannot escape from %s!", mon_nam(u.ustuck));
 +                nomul(0);
 +                return;
 +            }
 +            }
 +        }
 +
 +        mtmp = m_at(x,y);
 +        if (mtmp) {
 +            /* Don't attack if you're running, and can see it */
 +            /* We should never get here if forcefight */
 +            if (context.run &&
 +                ((!Blind && mon_visible(mtmp) &&
 +                  ((mtmp->m_ap_type != M_AP_FURNITURE &&
 +                mtmp->m_ap_type != M_AP_OBJECT) ||
 +                   Protection_from_shape_changers)) ||
 +                 sensemon(mtmp))) {
 +                nomul(0);
 +                context.move = 0;
 +                return;
 +            }
 +        }
 +    }
 +
 +    u.ux0 = u.ux;
 +    u.uy0 = u.uy;
 +    bhitpos.x = x;
 +    bhitpos.y = y;
 +    tmpr = &levl[x][y];
 +
 +    /* attack monster */
 +    if(mtmp) {
 +        nomul(0);
 +        /* only attack if we know it's there */
 +        /* or if we used the 'F' command to fight blindly */
 +        /* or if it hides_under, in which case we call attack() to print
 +         * the Wait! message.
 +         * This is different from ceiling hiders, who aren't handled in
 +         * attack().
 +         */
 +
 +        /* If they used a 'm' command, trying to move onto a monster
 +         * prints the below message and wastes a turn.  The exception is
 +         * if the monster is unseen and the player doesn't remember an
 +         * invisible monster--then, we fall through to attack() and
 +         * attack_check(), which still wastes a turn, but prints a
 +         * different message and makes the player remember the monster.                    */
 +        if(context.nopick &&
 +          (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){
 +        if(mtmp->m_ap_type && !Protection_from_shape_changers
 +                            && !sensemon(mtmp))
 +            stumble_onto_mimic(mtmp);
 +        else if (mtmp->mpeaceful && !Hallucination)
 +            pline("Pardon me, %s.", m_monnam(mtmp));
 +        else
 +            You("move right into %s.", mon_nam(mtmp));
 +        return;
 +        }
 +        if(context.forcefight || !mtmp->mundetected || sensemon(mtmp) ||
 +            ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) &&
 +            !is_safepet(mtmp))){
 +        /* try to attack; note that it might evade */
 +        /* also, we don't attack tame when _safepet_ */
 +        if(attack(mtmp)) return;
 +        }
 +    }
 +
 +    /* specifying 'F' with no monster wastes a turn */
 +    if (context.forcefight ||
 +        /* remembered an 'I' && didn't use a move command */
 +        (glyph_is_invisible(levl[x][y].glyph) && !context.nopick)) {
 +        struct obj *boulder = sobj_at(BOULDER, x, y);
 +        boolean explo = (Upolyd && attacktype(youmonst.data, AT_EXPL)),
 +            solid = !accessible(x, y);
 +        int glyph = glyph_at(x, y);   /* might be monster */
 +        char buf[BUFSZ];
 +
 +        /* if a statue is displayed at the target location,
 +           player is attempting to attack it [and boulder
 +           handlng below is suitable for handling that] */
 +        if (glyph_is_statue(glyph) ||
 +            (Hallucination && glyph_is_monster(glyph)))
 +            boulder = sobj_at(STATUE, x, y);
 +
 +        /* force fight at boulder/statue or wall/door while wielding
 +           pick:  start digging to break the boulder or wall */
 +        if (context.forcefight &&
 +            /* can we dig? */
 +            uwep && dig_typ(uwep, x, y) &&
 +            /* should we dig? */
 +            !glyph_is_invisible(glyph) &&
 +            !glyph_is_monster(glyph)) {
 +            (void)use_pick_axe2(uwep);
 +            return;
 +        }
 +
 +        if (boulder)
 +            Strcpy(buf, ansimpleoname(boulder));
 +        else if (solid)
 +            Strcpy(buf, the(defsyms[glyph_to_cmap(glyph)].explanation));
 +        else if (!Underwater)
 +            Strcpy(buf, "thin air");
 +        else if (is_pool(x, y))
 +            Strcpy(buf, "empty water");
 +        else  /* Underwater, targetting non-water */
 +            Sprintf(buf, "a vacant spot on the %s", surface(x,y));
 +        You("%s%s %s.",
 +            !(boulder || solid) ? "" :
 +            !explo ? "harmlessly " : "futilely ",
 +            explo ? "explode at" : "attack",
 +            buf);
 +        unmap_object(x, y); /* known empty -- remove 'I' if present */
 +        if (boulder) map_object(boulder, TRUE);
 +        newsym(x, y);
 +        nomul(0);
 +        if (explo) {
 +            wake_nearby();
 +            u.mh = -1;                /* dead in the current form */
 +            rehumanize();
 +        }
 +        return;
 +    }
 +    if (glyph_is_invisible(levl[x][y].glyph)) {
 +        unmap_object(x, y);
 +        newsym(x, y);
 +    }
 +    /* not attacking an animal, so we try to move */
 +    if ((u.dx || u.dy) && u.usteed && stucksteed(FALSE)) {
 +        nomul(0);
 +        return;
 +    }
 +    if(!youmonst.data->mmove) {
 +        You("are rooted %s.",
 +            Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
 +            "in place" : "to the ground");
 +        nomul(0);
 +        return;
 +    }
 +    if(u.utrap) {
 +        if (!trapmove(x, y, trap)) return;
 +    }
 +
 +    if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) {
 +        context.move = 0;
 +        nomul(0);
 +        return;
 +    }
 +
 +    /* Move ball and chain.  */
 +    if (Punished)
 +        if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy,
 +            &cause_delay, TRUE))
 +        return;
 +
 +    /* Check regions entering/leaving */
 +    if (!in_out_region(x,y))
 +        return;
 +
 +    /* now move the hero */
 +    mtmp = m_at(x, y);
 +    u.ux += u.dx;
 +    u.uy += u.dy;
 +    /* Move your steed, too */
 +    if (u.usteed) {
 +        u.usteed->mx = u.ux;
 +        u.usteed->my = u.uy;
 +        exercise_steed();
 +    }
 +
 +    /*
 +     * If safepet at destination then move the pet to the hero's
 +     * previous location using the same conditions as in attack().
 +     * there are special extenuating circumstances:
 +     * (1) if the pet dies then your god angers,
 +     * (2) if the pet gets trapped then your god may disapprove,
 +     * (3) if the pet was already trapped and you attempt to free it
 +     * not only do you encounter the trap but you may frighten your
 +     * pet causing it to go wild!  moral: don't abuse this privilege.
 +     *
 +     * Ceiling-hiding pets are skipped by this section of code, to
 +     * be caught by the normal falling-monster code.
 +     */
 +    if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) {
 +        /* if trapped, there's a chance the pet goes wild */
 +        if (mtmp->mtrapped) {
 +        if (!rn2(mtmp->mtame)) {
 +            mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0;
 +            if (mtmp->mleashed) m_unleash(mtmp, TRUE);
 +            growl(mtmp);
 +        } else {
 +            yelp(mtmp);
 +        }
 +        }
 +        mtmp->mundetected = 0;
 +        if (mtmp->m_ap_type) seemimic(mtmp);
 +        else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my);
 +
 +        if (mtmp->mtrapped &&
 +            (trap = t_at(mtmp->mx, mtmp->my)) != 0 &&
 +            (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&
 +            sobj_at(BOULDER, trap->tx, trap->ty)) {
 +        /* can't swap places with pet pinned in a pit by a boulder */
 +        u.ux = u.ux0,  u.uy = u.uy0;  /* didn't move after all */
 +        } else if (u.ux0 != x && u.uy0 != y && NODIAG(mtmp->data - mons)) {
 +        /* can't swap places when pet can't move to your spot */
 +        u.ux = u.ux0,  u.uy = u.uy0;
 +        You("stop.  %s can't move diagonally.",
 +            upstart(y_monnam(mtmp)));
 +        } else if (u.ux0 != x && u.uy0 != y &&
 +               bad_rock(mtmp->data, x, u.uy0) &&
 +               bad_rock(mtmp->data, u.ux0, y) &&
 +               (bigmonst(mtmp->data) || (curr_mon_load(mtmp) > 600))) {
 +        /* can't swap places when pet won't fit thru the opening */
 +        u.ux = u.ux0,  u.uy = u.uy0;  /* didn't move after all */
 +        You("stop.  %s won't fit through.", upstart(y_monnam(mtmp)));
 +        } else {
 +        char pnambuf[BUFSZ];
 +
 +        /* save its current description in case of polymorph */
 +        Strcpy(pnambuf, y_monnam(mtmp));
 +        mtmp->mtrapped = 0;
 +        remove_monster(x, y);
 +        place_monster(mtmp, u.ux0, u.uy0);
 +        newsym(x, y);
 +        newsym(u.ux0, u.uy0);
 +
 +        You("%s %s.", mtmp->mtame ? "swap places with" : "frighten",
 +            pnambuf);
 +
 +        /* check for displacing it into pools and traps */
 +        switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) {
 +        case 0:
 +            break;
 +        case 1:               /* trapped */
 +        case 3:               /* changed levels */
 +            /* there's already been a trap message, reinforce it */
 +            abuse_dog(mtmp);
 +            adjalign(-3);
 +            break;
 +        case 2:
 +            /* drowned or died...
 +             * you killed your pet by direct action, so get experience
 +             * and possibly penalties;
 +             * we want the level gain message, if it happens, to occur
 +             * before the guilt message below
 +             */
 +          {
 +            /* minliquid() and mintrap() call mondead() rather than
 +               killed() so we duplicate some of the latter here */
 +            int tmp, mndx;
 +
 +            u.uconduct.killer++;
 +            mndx = monsndx(mtmp->data);
 +            tmp = experience(mtmp, (int)mvitals[mndx].died);
 +            more_experienced(tmp, 0);
 +            newexplevel();    /* will decide if you go up */
 +          }
 +            /* That's no way to treat a pet!  Your god gets angry.
 +             *
 +             * [This has always been pretty iffy.  Why does your
 +             * patron deity care at all, let alone enough to get mad?]
 +             */
 +            if (rn2(4)) {
 +            You_feel("guilty about losing your pet like this.");
 +            u.ugangr++;
 +            adjalign(-15);
 +            }
 +            break;
 +        default:
 +            pline("that's strange, unknown mintrap result!");
 +            break;
 +        }
 +        }
 +    }
 +
 +    reset_occupations();
 +    if (context.run) {
 +        if ( context.run < 8 )
 +        if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) ||
 +            IS_FURNITURE(tmpr->typ))
 +            nomul(0);
 +    }
 +
 +    if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) ||
 +        u.dx || u.dy)
 +        (void) hideunder(&youmonst);
 +
 +    /*
 +     * Mimics (or whatever) become noticeable if they move and are
 +     * imitating something that doesn't move.  We could extend this
 +     * to non-moving monsters...
 +     */
 +    if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT
 +                || youmonst.m_ap_type == M_AP_FURNITURE))
 +        youmonst.m_ap_type = M_AP_NOTHING;
 +
 +    check_leash(u.ux0,u.uy0);
 +
 +    if(u.ux0 != u.ux || u.uy0 != u.uy) {
 +        u.umoved = TRUE;
 +        /* Clean old position -- vision_recalc() will print our new one. */
 +        newsym(u.ux0,u.uy0);
 +        /* Since the hero has moved, adjust what can be seen/unseen. */
 +        vision_recalc(1);     /* Do the work now in the recover time. */
 +        invocation_message();
 +    }
 +
 +    if (Punished)                             /* put back ball and chain */
 +        move_bc(0,bc_control,ballx,bally,chainx,chainy);
 +
 +    spoteffects(TRUE);
 +
 +    /* delay next move because of ball dragging */
 +    /* must come after we finished picking up, in spoteffects() */
 +    if (cause_delay) {
 +        nomul(-2);
            multi_reason = "dragging an iron ball";
 -          nomovemsg = "";
 -      }
 -
 -      if (context.run && flags.runmode != RUN_TPORT) {
 -          /* display every step or every 7th step depending upon mode */
 -          if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
 -              if (flags.time) context.botl = 1;
 -              curs_on_u();
 -              delay_output();
 -              if (flags.runmode == RUN_CRAWL) {
 -                  delay_output();
 -                  delay_output();
 -                  delay_output();
 -                  delay_output();
 -              }
 -          }
 -      }
 +        nomovemsg = "";
 +    }
 +
 +    if (context.run && flags.runmode != RUN_TPORT) {
 +        /* display every step or every 7th step depending upon mode */
 +        if (flags.runmode != RUN_LEAP || !(moves % 7L)) {
 +        if (flags.time) context.botl = 1;
 +        curs_on_u();
 +        delay_output();
 +        if (flags.runmode == RUN_CRAWL) {
 +            delay_output();
 +            delay_output();
 +            delay_output();
 +            delay_output();
 +        }
 +        }
 +    }
  }
  
  /* combat increases metabolism */
diff --cc src/mon.c
index 9e511670b6d7d1a00cd4a54de55f7a15369abac1,5fd4f22dd8379fd6cd5a14f50c02abe60a894b52..93fef1b0c030a70afb86fc2fe4306f5a7bc3215d
+++ b/src/mon.c
@@@ -146,186 -146,168 +146,187 @@@ make_corpse(mtmp,corpseflags
  register struct monst *mtmp;
  unsigned corpseflags;
  {
 -      register struct permonst *mdat = mtmp->data;
 -      int num;
 -      struct obj *obj = (struct obj *)0;
 -      int x = mtmp->mx, y = mtmp->my;
 -      int mndx = monsndx(mdat);
 -      unsigned corpstatflags = corpseflags;
 -      boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0);
 -
 -      switch(mndx) {
 -          case PM_GRAY_DRAGON:
 -          case PM_SILVER_DRAGON:
 +    register struct permonst *mdat = mtmp->data;
 +    int num;
 +    struct obj *obj = (struct obj *)0;
 +    struct obj* otmp = (struct obj*)0;
 +    int x = mtmp->mx, y = mtmp->my;
 +    int mndx = monsndx(mdat);
 +    unsigned corpstatflags = corpseflags;
 +    boolean burythem = ((corpstatflags & CORPSTAT_BURIED) != 0);
 +
 +    switch(mndx) {
 +        case PM_GRAY_DRAGON:
 +        case PM_SILVER_DRAGON:
  #if 0 /* DEFERRED */
 -          case PM_SHIMMERING_DRAGON:
 +        case PM_SHIMMERING_DRAGON:
  #endif
 -          case PM_RED_DRAGON:
 -          case PM_ORANGE_DRAGON:
 -          case PM_WHITE_DRAGON:
 -          case PM_BLACK_DRAGON:
 -          case PM_BLUE_DRAGON:
 -          case PM_GREEN_DRAGON:
 -          case PM_YELLOW_DRAGON:
 -              /* Make dragon scales.  This assumes that the order of the */
 -              /* dragons is the same as the order of the scales.         */
 -              if (!rn2(mtmp->mrevived ? 20 : 3)) {
 -                  num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
 -                  obj = mksobj_at(num, x, y, FALSE, FALSE);
 -                  obj->spe = 0;
 -                  obj->cursed = obj->blessed = FALSE;
 -              }
 -              goto default_1;
 -
 -          case PM_WHITE_UNICORN:
 -          case PM_GRAY_UNICORN:
 -          case PM_BLACK_UNICORN:
 -              if (mtmp->mrevived && rn2(2)) {
 -                  if (canseemon(mtmp))
 -                      pline("%s recently regrown horn crumbles to dust.",
 -                            s_suffix(Monnam(mtmp)));
 -              } else {
 -                  obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
 -                  if (obj && mtmp->mrevived) obj->degraded_horn = 1;
 -              }
 -              goto default_1;
 -          case PM_LONG_WORM:
 -              (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
 -              goto default_1;
 -          case PM_VAMPIRE:
 -          case PM_VAMPIRE_LORD:
 -              /* include mtmp in the mkcorpstat() call */
 -              num = undead_to_corpse(mndx);
 -              corpstatflags |= CORPSTAT_INIT;
 -              obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
 -              obj->age -= 100;                /* this is an *OLD* corpse */
 -              break;
 -          case PM_KOBOLD_MUMMY:
 -          case PM_DWARF_MUMMY:
 -          case PM_GNOME_MUMMY:
 -          case PM_ORC_MUMMY:
 -          case PM_ELF_MUMMY:
 -          case PM_HUMAN_MUMMY:
 -          case PM_GIANT_MUMMY:
 -          case PM_ETTIN_MUMMY:
 -          case PM_KOBOLD_ZOMBIE:
 -          case PM_DWARF_ZOMBIE:
 -          case PM_GNOME_ZOMBIE:
 -          case PM_ORC_ZOMBIE:
 -          case PM_ELF_ZOMBIE:
 -          case PM_HUMAN_ZOMBIE:
 -          case PM_GIANT_ZOMBIE:
 -          case PM_ETTIN_ZOMBIE:
 -              num = undead_to_corpse(mndx);
 -              corpstatflags |= CORPSTAT_INIT;
 -              obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
 -              obj->age -= 100;                /* this is an *OLD* corpse */
 -              break;
 -          case PM_IRON_GOLEM:
 -              num = d(2,6);
 -              while (num--)
 -                      obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
 -              free_mname(mtmp);       /* don't christen obj */
 -              break;
 -          case PM_GLASS_GOLEM:
 -              num = d(2,4);   /* very low chance of creating all glass gems */
 -              while (num--)
 -                      obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
 -              free_mname(mtmp);
 -              break;
 -          case PM_CLAY_GOLEM:
 -              obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
 -              obj->quan = (long)(rn2(20) + 50);
 -              obj->owt = weight(obj);
 -              free_mname(mtmp);
 -              break;
 -          case PM_STONE_GOLEM:
 -              corpstatflags &= ~CORPSTAT_INIT;
 -              obj = mkcorpstat(STATUE, (struct monst *)0,
 -                      mdat, x, y, corpstatflags);
 -              break;
 -          case PM_WOOD_GOLEM:
 -              num = d(2,4);
 -              while(num--) {
 -                      obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
 -              }
 -              free_mname(mtmp);
 -              break;
 -          case PM_LEATHER_GOLEM:
 -              num = d(2,4);
 -              while(num--)
 -                      obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
 -              free_mname(mtmp);
 -              break;
 -          case PM_GOLD_GOLEM:
 -              /* Good luck gives more coins */
 -              obj = mkgold((long)(200 - rnl(101)), x, y);
 -              free_mname(mtmp);
 -              break;
 -          case PM_PAPER_GOLEM:
 -              num = rnd(4);
 -              while (num--)
 -                      obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
 -              free_mname(mtmp);
 -              break;
 -          default_1:
 -          default:
 -              if (mvitals[mndx].mvflags & G_NOCORPSE)
 -                  return (struct obj *)0;
 -              else {
 -                  corpstatflags |= CORPSTAT_INIT;
 -                  /* preserve the unique traits of some creatures */
 -                  obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
 -                                   mdat, x, y, corpstatflags);
 -                  if (burythem) {
 +        case PM_RED_DRAGON:
 +        case PM_ORANGE_DRAGON:
 +        case PM_WHITE_DRAGON:
 +        case PM_BLACK_DRAGON:
 +        case PM_BLUE_DRAGON:
 +        case PM_GREEN_DRAGON:
 +        case PM_YELLOW_DRAGON:
 +        /* Make dragon scales.  This assumes that the order of the */
 +        /* dragons is the same as the order of the scales.       */
 +        if (!rn2(mtmp->mrevived ? 20 : 3)) {
 +            num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON;
 +            obj = mksobj_at(num, x, y, FALSE, FALSE);
 +            obj->spe = 0;
 +            obj->cursed = obj->blessed = FALSE;
 +        }
 +        goto default_1;
 +
 +        case PM_WHITE_UNICORN:
 +        case PM_GRAY_UNICORN:
 +        case PM_BLACK_UNICORN:
 +        if (mtmp->mrevived && rn2(2)) {
 +            if (canseemon(mtmp))
 +            pline("%s recently regrown horn crumbles to dust.",
 +                  s_suffix(Monnam(mtmp)));
 +        } else {
 +            obj = mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE);
 +            if (obj && mtmp->mrevived) obj->degraded_horn = 1;
 +        }
 +        goto default_1;
 +        case PM_LONG_WORM:
 +        (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE);
 +        goto default_1;
 +        case PM_VAMPIRE:
 +        case PM_VAMPIRE_LORD:
 +        /* include mtmp in the mkcorpstat() call */
 +        num = undead_to_corpse(mndx);
 +        corpstatflags |= CORPSTAT_INIT;
 +        obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
 +        obj->age -= 100;              /* this is an *OLD* corpse */
 +        break;
 +        case PM_KOBOLD_MUMMY:
 +        case PM_DWARF_MUMMY:
 +        case PM_GNOME_MUMMY:
 +        case PM_ORC_MUMMY:
 +        case PM_ELF_MUMMY:
 +        case PM_HUMAN_MUMMY:
 +        case PM_GIANT_MUMMY:
 +        case PM_ETTIN_MUMMY:
 +        case PM_KOBOLD_ZOMBIE:
 +        case PM_DWARF_ZOMBIE:
 +        case PM_GNOME_ZOMBIE:
 +        case PM_ORC_ZOMBIE:
 +        case PM_ELF_ZOMBIE:
 +        case PM_HUMAN_ZOMBIE:
 +        case PM_GIANT_ZOMBIE:
 +        case PM_ETTIN_ZOMBIE:
 +        num = undead_to_corpse(mndx);
 +        corpstatflags |= CORPSTAT_INIT;
 +        obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
 +        obj->age -= 100;              /* this is an *OLD* corpse */
 +        break;
 +        case PM_IRON_GOLEM:
 +        num = d(2,6);
 +        while (num--)
 +            obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE);
 +        free_mname(mtmp);     /* don't christen obj */
 +        break;
 +        case PM_GLASS_GOLEM:
 +        num = d(2,4);   /* very low chance of creating all glass gems */
 +        while (num--)
 +            obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE);
 +        free_mname(mtmp);
 +        break;
 +        case PM_CLAY_GOLEM:
 +        obj = mksobj_at(ROCK, x, y, FALSE, FALSE);
 +        obj->quan = (long)(rn2(20) + 50);
 +        obj->owt = weight(obj);
 +        free_mname(mtmp);
 +        break;
 +        case PM_STONE_GOLEM:
 +            corpstatflags &= ~CORPSTAT_INIT;
 +        obj = mkcorpstat(STATUE, (struct monst *)0,
 +            mdat, x, y, corpstatflags);
 +        break;
 +        case PM_WOOD_GOLEM:
 +        num = d(2,4);
 +        while(num--) {
 +            obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE);
 +        }
 +        free_mname(mtmp);
 +        break;
 +        case PM_LEATHER_GOLEM:
 +        num = d(2,4);
 +        while(num--)
 +            obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE);
 +        free_mname(mtmp);
 +        break;
 +        case PM_GOLD_GOLEM:
 +        /* Good luck gives more coins */
 +        obj = mkgold((long)(200 - rnl(101)), x, y);
 +        free_mname(mtmp);
 +        break;
 +        case PM_PAPER_GOLEM:
 +        num = rnd(4);
 +        while (num--)
 +            obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE);
 +        free_mname(mtmp);
 +        break;
 +        /* expired puddings will congeal into a large blob 
 +           like dragons, relies on the order remaining consistent */ 
 +        case PM_GRAY_OOZE:
 +        case PM_BROWN_PUDDING:
 +        case PM_GREEN_SLIME:
 +        case PM_BLACK_PUDDING:
 +            /* we have to do this here because most other places
 +             * expect there to be an object coming back; not this one */
 +            obj = mksobj_at(GLOB_OF_BLACK_PUDDING - (PM_BLACK_PUDDING - mndx), 
 +                                x, y, TRUE, FALSE);
 +
 +            while ((obj && (otmp = obj_nexto(obj)) != (struct obj*)0)) {
 +                pline("The %s coalesce.", makeplural(obj_typename(obj->otyp)));
 +                obj = obj_meld(&obj, &otmp);
 +            }
 +            free_mname(mtmp);
 +            return obj;
 +        break;
 +        default_1:
 +        default:
 +            if (mvitals[mndx].mvflags & G_NOCORPSE)
 +                return (struct obj *)0;
 +            else {
 +                corpstatflags |= CORPSTAT_INIT;
 +                /* preserve the unique traits of some creatures */
 +                obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0,
 +                        mdat, x, y, corpstatflags);
 +                if (burythem) {
-                 (void) bury_an_obj(obj);
+                       boolean dealloc;
+                       (void) bury_an_obj(obj, &dealloc);
 -                      newsym(x, y);
 +                newsym(x, y);
-                 return obj;
+                       return (dealloc ? NULL : obj);
 -                  }
 -              }
 -              break;
 -      }
 -      /* All special cases should precede the G_NOCORPSE check */
 -
 -      /* if polymorph or undead turning has killed this monster,
 -         prevent the same attack beam from hitting its corpse */
 -      if (context.bypasses) bypass_obj(obj);
 -
 -      if (has_mname(mtmp))
 -          obj = oname(obj, MNAME(mtmp));
 -
 -      /* Avoid "It was hidden under a green mold corpse!" 
 -       *  during Blind combat. An unseen monster referred to as "it"
 -       *  could be killed and leave a corpse.  If a hider then hid
 -       *  underneath it, you could be told the corpse type of a
 -       *  monster that you never knew was there without this.
 -       *  The code in hitmu() substitutes the word "something"
 -       *  if the corpses obj->dknown is 0.
 -       */
 -      if (Blind && !sensemon(mtmp)) obj->dknown = 0;
 -
 -      stackobj(obj);
 -      newsym(x, y);
 -      return obj;
 +                }
 +            }
 +        break;
 +    }
 +    /* All special cases should precede the G_NOCORPSE check */
 +
 +    /* if polymorph or undead turning has killed this monster,
 +       prevent the same attack beam from hitting its corpse */
 +    if (context.bypasses) bypass_obj(obj);
 +
 +    if (has_mname(mtmp))
 +        obj = oname(obj, MNAME(mtmp));
 +
 +    /* Avoid "It was hidden under a green mold corpse!" 
 +     *  during Blind combat. An unseen monster referred to as "it"
 +     *  could be killed and leave a corpse.  If a hider then hid
 +     *  underneath it, you could be told the corpse type of a
 +     *  monster that you never knew was there without this.
 +     *  The code in hitmu() substitutes the word "something"
 +     *  if the corpses obj->dknown is 0.
 +     */
 +    if (Blind && !sensemon(mtmp)) obj->dknown = 0;
 +
 +    stackobj(obj);
 +    newsym(x, y);
 +    return obj;
  }
  
  /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */
diff --cc src/vision.c
index 50570c736d263674253a4a40116da8e75905f180,8abf63c798487945b985bc8f7602e6c38000c74b..64661718bf295027700764ef1266ccdff9942176
@@@ -2359,13 -2372,15 +2359,16 @@@ left_side(row, left_mark, right, limits
      int row, left_mark, right;
      char *limits;
  {
 -    int                 left, left_edge, nrow, deeper, result;
 -    register int  i;
 +    int left, left_edge, nrow, deeper, result;
 +    register int i;
      register char *rowp = NULL;
 -    char        *row_min = NULL, *row_max = NULL;
 -    int                 lim_min;
 +    char *row_min = NULL;
 +    char *row_max = NULL;
 +    int lim_min;
  
+ #ifdef GCC_WARN
+     rowp = row_min = row_max = 0;
+ #endif
      nrow    = row+step;
      deeper  = good_row(nrow) && (!limits || (*limits >= *(limits+1)));
      if(!vis_func) {