]> granicus.if.org Git - nethack/commitdiff
Merge branch 'master' into derek-farming
authorDerek S. Ray <derekray@gmail.com>
Fri, 10 Apr 2015 20:56:30 +0000 (16:56 -0400)
committerDerek S. Ray <derekray@gmail.com>
Fri, 10 Apr 2015 20:56:30 +0000 (16:56 -0400)
Reverse merge before final reintegration.

* master: (40 commits)
  Fix magic mapped dark room symbols
  Disclose extinct species alongside genocided ones
  ...

Conflicts:
doc/fixes35.0
src/do.c
src/files.c
src/invent.c
src/objnam.c
sys/share/pcmain.c

1  2 
doc/fixes35.0
include/extern.h
src/do.c
src/files.c
src/invent.c
src/monst.c
src/objnam.c
src/sp_lev.c
src/trap.c
sys/share/pcmain.c

diff --cc doc/fixes35.0
index a13f955c4dcc22717fd0facb9edfc393235b4825,44b891b764a276eaed2244de5bd3fbdaa7610f30..6a3e06d37aa8b85050452d90d4f727e07a8d5d83
@@@ -893,9 -892,8 +892,10 @@@ boomerang makes noise when hitting a si
  non-pet rust monsters would eat rust-proofed non-digestibles but ignore
        those non-digestibles otherwise
  kicking a grave may topple the gravestone
- allow showing legal jumping positions when asked for location to jump to
+ allow showing legal positions for stinking cloud, jumping and polearms
+       when asked for a location
 +cloned creatures (of any type) don't deathdrop items
 +pudding corpses behave somewhat differently than before
  
  
  Platform- and/or Interface-Specific Fixes
Simple merge
diff --cc src/do.c
index 5b27d283f93472cca91e7790588f0f0e3670afcf,8ba5005017a9223cf896338beef48b05c2d9008b..75b61159e8dd20e50a3f28dfcee9e69c50904516
+++ b/src/do.c
@@@ -931,36 -923,36 +931,36 @@@ d_level save_dlevel = {0, 0}
  STATIC_OVL int
  currentlevel_rewrite()
  {
 -      register int fd;
 -      char whynot[BUFSZ];
 -
 -      /* since level change might be a bit slow, flush any buffered screen
 -       *  output (like "you fall through a trap door") */
 -      mark_synch();
 -
 -      fd = create_levelfile(ledger_no(&u.uz), whynot);
 -      if (fd < 0) {
 -              /*
 -               * This is not quite impossible: e.g., we may have
 -               * exceeded our quota. If that is the case then we
 -               * cannot leave this level, and cannot save either.
 -               * Another possibility is that the directory was not
 -               * writable.
 -               */
 -              pline1(whynot);
 -              return -1;
 -      }
 +    register int fd;
 +    char whynot[BUFSZ];
 +
 +    /* since level change might be a bit slow, flush any buffered screen
 +     *  output (like "you fall through a trap door") */
 +    mark_synch();
 +
 +    fd = create_levelfile(ledger_no(&u.uz), whynot);
 +    if (fd < 0) {
 +        /*
 +         * This is not quite impossible: e.g., we may have
 +         * exceeded our quota. If that is the case then we
 +         * cannot leave this level, and cannot save either.
 +         * Another possibility is that the directory was not
 +         * writable.
 +         */
 +        pline1(whynot);
 +        return -1;
 +    }
  
  #ifdef MFLOPPY
 -      if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) {
 +    if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) {
-         (void) close(fd);
+               (void) nhclose(fd);
 -              delete_levelfile(ledger_no(&u.uz));
 -              pline("NetHack is out of disk space for making levels!");
 -              You("can save, quit, or continue playing.");
 -              return -1;
 -      }
 +        delete_levelfile(ledger_no(&u.uz));
 +        pline("NetHack is out of disk space for making levels!");
 +        You("can save, quit, or continue playing.");
 +        return -1;
 +    }
  #endif
 -      return fd;
 +    return fd;
  }
  
  #ifdef INSURANCE
@@@ -1034,382 -1026,384 +1034,384 @@@ 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);
 +    /* 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);
+               (void) nhclose(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");
 -          }
 -      }
 +        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) || Is_airlevel(&u.uz))
 -              movebubbles();
 +        movebubbles();
+       else if (Is_firelevel(&u.uz))
+           fumaroles();
  
 -      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 02843bd1f77343d6ac3fefad26f17998a6af917b,9b9d0946327b52a4754d36ab22383fcf2b3e6530..84faacab9b16d7aa264ce2035d4d331c7ec5693f
@@@ -636,29 -636,36 +636,36 @@@ int lev, oflag
  void
  really_close()
  {
 -      int fd = lftrack.fd;
 -      lftrack.nethack_thinks_it_is_open = FALSE;
 -      lftrack.fd = -1;
 -      lftrack.oflag = 0;
 -      if (fd != -1)
 +    int fd = lftrack.fd;
 +    lftrack.nethack_thinks_it_is_open = FALSE;
 +    lftrack.fd = -1;
 +    lftrack.oflag = 0;
 +    if (fd != -1)
-         (void)_close(fd);
+               (void)close(fd);
 -      return;
 +    return;
  }
  
  int
- close(fd)
nhclose(fd)
  int fd;
  {
 -      if (lftrack.fd == fd) {
 -              really_close(); /* close it, but reopen it to hold it */
 -              fd = open_levelfile(0, (char *)0);
 -              lftrack.nethack_thinks_it_is_open = FALSE;
 -              return 0;
 -      }
 +    if (lftrack.fd == fd) {
 +        really_close();       /* close it, but reopen it to hold it */
 +        fd = open_levelfile(0, (char *)0);
 +        lftrack.nethack_thinks_it_is_open = FALSE;
 +        return 0;
 +    }
-     return _close(fd);
+       return close(fd);
+ }
+ #else
+ int
+ nhclose(fd)
+ int fd;
+ {
+       return close(fd);
  }
  #endif
-     
  /* ----------  END LEVEL FILE HANDLING ----------- */
  
  
@@@ -981,25 -988,25 +988,25 @@@ delete_savefile(
  int
  restore_saved_game()
  {
 -      const char *fq_save;
 -      int fd;
 +    const char *fq_save;
 +    int fd;
  
 -      reset_restpref();
 -      set_savefile_name(TRUE);
 +    reset_restpref();
 +    set_savefile_name(TRUE);
  #ifdef MFLOPPY
 -      if (!saveDiskPrompt(1))
 -          return -1;
 +    if (!saveDiskPrompt(1))
 +        return -1;
  #endif /* MFLOPPY */
 -      fq_save = fqname(SAVEF, SAVEPREFIX, 0);
 +    fq_save = fqname(SAVEF, SAVEPREFIX, 0);
  
 -      nh_uncompress(fq_save);
 -      if ((fd = open_savefile()) < 0) return fd;
 +    nh_uncompress(fq_save);
 +    if ((fd = open_savefile()) < 0) return fd;
  
 -      if (validate(fd, fq_save) != 0) {
 +    if (validate(fd, fq_save) != 0) {
-         (void) close(fd),  fd = -1;
+           (void) nhclose(fd),  fd = -1;
 -          (void) delete_savefile();
 -      }
 -      return fd;
 +        (void) delete_savefile();
 +    }
 +    return fd;
  }
  
  #if defined(SELECTSAVED)
@@@ -1016,12 -1023,12 +1023,12 @@@ const char* filename
  #  endif
      nh_uncompress(SAVEF);
      if ((fd = open_savefile()) >= 0) {
 -      if (validate(fd, filename)==0) {
 -          char tplname[PL_NSIZ];
 -          get_plname_from_file(fd, tplname);
 -          result = dupstr(tplname);
 -      }
 +    if (validate(fd, filename)==0) {
 +        char tplname[PL_NSIZ];
 +        get_plname_from_file(fd, tplname);
 +        result = dupstr(tplname);
 +    }
-     (void) close(fd);
+       (void) nhclose(fd);
      }
      nh_compress(SAVEF);
  
@@@ -1413,124 -1420,124 +1420,124 @@@ docompress_file(filename, uncomp
  const char *filename;
  boolean uncomp;
  {
-     gzFile *compressedfile;
+       gzFile compressedfile;
 -      FILE *uncompressedfile;
 -      char cfn[256];
 -      char buf[1024];
 -      unsigned len, len2;
 -
 -      if (!make_compressed_name(filename, cfn))
 -              return;
 -
 -      if (!uncomp) {
 -              /* Open the input and output files */
 -              /* Note that gzopen takes "wb" as its mode, even on systems where
 -                 fopen takes "r" and "w" */
 -
 -              uncompressedfile = fopen(filename, RDBMODE);
 -              if (!uncompressedfile) {
 -                      pline("Error in zlib docompress_file %s", filename);
 -                      return;
 -              }
 -              compressedfile = gzopen(cfn, "wb");
 -              if (compressedfile == NULL) {
 -                      if (errno == 0) {
 -                              pline("zlib failed to allocate memory");
 -                      } else {
 -                              panic("Error in docompress_file %d",
 -                                      errno);
 -                      }
 -                      fclose(uncompressedfile);
 -                      return;
 -              }
 -
 -              /* Copy from the uncompressed to the compressed file */
 -
 -              while (1) {
 -                      len = fread(buf, 1, sizeof(buf), uncompressedfile);
 -                      if (ferror(uncompressedfile)) {
 -                              pline("Failure reading uncompressed file");
 -                              pline("Can't compress %s.", filename);
 -                              fclose(uncompressedfile);
 -                              gzclose(compressedfile);
 -                              (void)unlink(cfn);
 -                              return;
 -                      }
 -                      if (len == 0) break;    /* End of file */
 -
 -                      len2 = gzwrite(compressedfile, buf, len);
 -                      if (len2 == 0) {
 -                              pline("Failure writing compressed file");
 -                              pline("Can't compress %s.", filename);
 -                              fclose(uncompressedfile);
 -                              gzclose(compressedfile);
 -                              (void)unlink(cfn);
 -                              return;
 -                      }
 -              }
 -
 -              fclose(uncompressedfile);
 -              gzclose(compressedfile);
 -
 -              /* Delete the file left behind */
 -
 -              (void)unlink(filename);
 -
 -      } else {        /* uncomp */
 -
 -              /* Open the input and output files */
 -              /* Note that gzopen takes "rb" as its mode, even on systems where
 -                 fopen takes "r" and "w" */
 -
 -              compressedfile = gzopen(cfn, "rb");
 -              if (compressedfile == NULL) {
 -                      if (errno == 0) {
 -                              pline("zlib failed to allocate memory");
 -                      } else if (errno != ENOENT) {
 -                              panic("Error in zlib docompress_file %s, %d",
 -                                      filename, errno);
 -                      }
 -                      return;
 -              }
 -              uncompressedfile = fopen(filename, WRBMODE);
 -              if (!uncompressedfile) {
 -                      pline("Error in zlib docompress file uncompress %s",
 -                              filename);
 -                      gzclose(compressedfile);
 -                      return;
 -              }
 -
 -              /* Copy from the compressed to the uncompressed file */
 -
 -              while (1) {
 -                      len = gzread(compressedfile, buf, sizeof(buf));
 -                      if (len == (unsigned)-1) {
 -                              pline("Failure reading compressed file");
 -                              pline("Can't uncompress %s.", filename);
 -                              fclose(uncompressedfile);
 -                              gzclose(compressedfile);
 -                              (void)unlink(filename);
 -                              return;
 -                      }
 -                      if (len == 0) break;    /* End of file */
 -
 -                      fwrite(buf, 1, len, uncompressedfile);
 -                      if (ferror(uncompressedfile)) {
 -                              pline("Failure writing uncompressed file");
 -                              pline("Can't uncompress %s.", filename);
 -                              fclose(uncompressedfile);
 -                              gzclose(compressedfile);
 -                              (void)unlink(filename);
 -                              return;
 -                      }
 -              }
 -
 -              fclose(uncompressedfile);
 -              gzclose(compressedfile);
 -
 -              /* Delete the file left behind */
 -              (void)unlink(cfn);
 -      }
 +    FILE *uncompressedfile;
 +    char cfn[256];
 +    char buf[1024];
 +    unsigned len, len2;
 +
 +    if (!make_compressed_name(filename, cfn))
 +        return;
 +
 +    if (!uncomp) {
 +        /* Open the input and output files */
 +        /* Note that gzopen takes "wb" as its mode, even on systems where
 +           fopen takes "r" and "w" */
 +
 +        uncompressedfile = fopen(filename, RDBMODE);
 +        if (!uncompressedfile) {
 +            pline("Error in zlib docompress_file %s", filename);
 +            return;
 +        }
 +        compressedfile = gzopen(cfn, "wb");
 +        if (compressedfile == NULL) {
 +            if (errno == 0) {
 +                pline("zlib failed to allocate memory");
 +            } else {
 +                panic("Error in docompress_file %d",
 +                    errno);
 +            }
 +            fclose(uncompressedfile);
 +            return;
 +        }
 +
 +        /* Copy from the uncompressed to the compressed file */
 +
 +        while (1) {
 +            len = fread(buf, 1, sizeof(buf), uncompressedfile);
 +            if (ferror(uncompressedfile)) {
 +                pline("Failure reading uncompressed file");
 +                pline("Can't compress %s.", filename);
 +                fclose(uncompressedfile);
 +                gzclose(compressedfile);
 +                (void)unlink(cfn);
 +                return;
 +            }
 +            if (len == 0) break;      /* End of file */
 +
 +            len2 = gzwrite(compressedfile, buf, len);
 +            if (len2 == 0) {
 +                pline("Failure writing compressed file");
 +                pline("Can't compress %s.", filename);
 +                fclose(uncompressedfile);
 +                gzclose(compressedfile);
 +                (void)unlink(cfn);
 +                return;
 +            }
 +        }
 +
 +        fclose(uncompressedfile);
 +        gzclose(compressedfile);
 +
 +        /* Delete the file left behind */
 +
 +        (void)unlink(filename);
 +
 +    } else {  /* uncomp */
 +
 +        /* Open the input and output files */
 +        /* Note that gzopen takes "rb" as its mode, even on systems where
 +           fopen takes "r" and "w" */
 +
 +        compressedfile = gzopen(cfn, "rb");
 +        if (compressedfile == NULL) {
 +            if (errno == 0) {
 +                pline("zlib failed to allocate memory");
 +            } else if (errno != ENOENT) {
 +                panic("Error in zlib docompress_file %s, %d",
 +                    filename, errno);
 +            }
 +            return;
 +        }
 +        uncompressedfile = fopen(filename, WRBMODE);
 +        if (!uncompressedfile) {
 +            pline("Error in zlib docompress file uncompress %s",
 +                filename);
 +            gzclose(compressedfile);
 +            return;
 +        }
 +
 +        /* Copy from the compressed to the uncompressed file */
 +
 +        while (1) {
 +            len = gzread(compressedfile, buf, sizeof(buf));
 +            if (len == (unsigned)-1) {
 +                pline("Failure reading compressed file");
 +                pline("Can't uncompress %s.", filename);
 +                fclose(uncompressedfile);
 +                gzclose(compressedfile);
 +                (void)unlink(filename);
 +                return;
 +            }
 +            if (len == 0) break;      /* End of file */
 +
 +            fwrite(buf, 1, len, uncompressedfile);
 +            if (ferror(uncompressedfile)) {
 +                pline("Failure writing uncompressed file");
 +                pline("Can't uncompress %s.", filename);
 +                fclose(uncompressedfile);
 +                gzclose(compressedfile);
 +                (void)unlink(filename);
 +                return;
 +            }
 +        }
 +
 +        fclose(uncompressedfile);
 +        gzclose(compressedfile);
 +
 +        /* Delete the file left behind */
 +        (void)unlink(cfn);
 +    }
  }
  #endif /* RLC 09 Mar 1999: End ZLIB patch */
  
@@@ -1774,10 -1781,10 +1781,10 @@@ const char *filename
  #endif
  
  #if defined(UNIX) || defined(VMS)
 -              if (unlink(lockname) < 0)
 -                      HUP raw_printf("Can't unlink %s.", lockname);
 +        if (unlink(lockname) < 0)
 +            HUP raw_printf("Can't unlink %s.", lockname);
  # ifdef NO_FILE_LINKS
-         (void) close(lockfd);
+               (void) nhclose(lockfd);
  # endif
  
  #endif  /* UNIX || VMS */
@@@ -2185,286 -2194,288 +2192,288 @@@ int               src
        } 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, "BOULDER", 3)) {
 +        (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
 +                  1, "BOULDER");
+       } else if (match_varname(buf, "MENUCOLOR", 9)) {
+           (void) add_menu_coloring(bufp);
 -      } 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, "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
@@@ -2917,66 -2928,66 +2926,66 @@@ const char *dir UNUSED_if_not_OS2_CODEV
  #if defined(PRAGMA_UNUSED) && !defined(OS2_CODEVIEW)
  # pragma unused(dir)
  #endif
 -      const char *fq_record;
 -      int fd;
 +    const char *fq_record;
 +    int fd;
  
  #if defined(UNIX) || defined(VMS)
 -      fq_record = fqname(RECORD, SCOREPREFIX, 0);
 -      fd = open(fq_record, O_RDWR, 0);
 -      if (fd >= 0) {
 +    fq_record = fqname(RECORD, SCOREPREFIX, 0);
 +    fd = open(fq_record, O_RDWR, 0);
 +    if (fd >= 0) {
  # ifdef VMS   /* must be stream-lf to use UPDATE_RECORD_IN_PLACE */
 -          if (!file_is_stmlf(fd)) {
 -              raw_printf(
 -                    "Warning: scoreboard file %s is not in stream_lf format",
 -                         fq_record);
 -              wait_synch();
 -          }
 +        if (!file_is_stmlf(fd)) {
 +        raw_printf(
 +              "Warning: scoreboard file %s is not in stream_lf format",
 +                   fq_record);
 +        wait_synch();
 +        }
  # endif
-         (void) close(fd);     /* RECORD is accessible */
+           (void) nhclose(fd); /* RECORD is accessible */
 -      } else if ((fd = open(fq_record, O_CREAT|O_RDWR, FCMASK)) >= 0) {
 +    } else if ((fd = open(fq_record, O_CREAT|O_RDWR, FCMASK)) >= 0) {
-         (void) close(fd);     /* RECORD newly created */
+           (void) nhclose(fd); /* RECORD newly created */
  # if defined(VMS) && !defined(SECURE)
 -          /* Re-protect RECORD with world:read+write+execute+delete access. */
 -          (void) chmod(fq_record, FCMASK | 007);
 +        /* Re-protect RECORD with world:read+write+execute+delete access. */
 +        (void) chmod(fq_record, FCMASK | 007);
  # endif /* VMS && !SECURE */
 -      } else {
 -          raw_printf("Warning: cannot write scoreboard file %s", fq_record);
 -          wait_synch();
 -      }
 +    } else {
 +        raw_printf("Warning: cannot write scoreboard file %s", fq_record);
 +        wait_synch();
 +    }
  #endif  /* !UNIX && !VMS */
  #if defined(MICRO) || defined(WIN32)
 -      char tmp[PATHLEN];
 +    char tmp[PATHLEN];
  
  # ifdef OS2_CODEVIEW   /* explicit path on opening for OS/2 */
 -      /* how does this work when there isn't an explicit path or fopenp
 -       * for later access to the file via fopen_datafile? ? */
 -      (void) strncpy(tmp, dir, PATHLEN - 1);
 -      tmp[PATHLEN-1] = '\0';
 -      if ((strlen(tmp) + 1 + strlen(RECORD)) < (PATHLEN - 1)) {
 -              append_slash(tmp);
 -              Strcat(tmp, RECORD);
 -      }
 -      fq_record = tmp;
 +    /* how does this work when there isn't an explicit path or fopenp
 +     * for later access to the file via fopen_datafile? ? */
 +    (void) strncpy(tmp, dir, PATHLEN - 1);
 +    tmp[PATHLEN-1] = '\0';
 +    if ((strlen(tmp) + 1 + strlen(RECORD)) < (PATHLEN - 1)) {
 +        append_slash(tmp);
 +        Strcat(tmp, RECORD);
 +    }
 +    fq_record = tmp;
  # else
 -      Strcpy(tmp, RECORD);
 -      fq_record = fqname(RECORD, SCOREPREFIX, 0);
 +    Strcpy(tmp, RECORD);
 +    fq_record = fqname(RECORD, SCOREPREFIX, 0);
  # endif
  
 -      if ((fd = open(fq_record, O_RDWR)) < 0) {
 -          /* try to create empty record */
 +    if ((fd = open(fq_record, O_RDWR)) < 0) {
 +        /* try to create empty record */
  # if defined(AZTEC_C) || defined(_DCC) || (defined(__GNUC__) && defined(__AMIGA__))
 -          /* Aztec doesn't use the third argument */
 -          /* DICE doesn't like it */
 -          if ((fd = open(fq_record, O_CREAT|O_RDWR)) < 0) {
 +        /* Aztec doesn't use the third argument */
 +        /* DICE doesn't like it */
 +        if ((fd = open(fq_record, O_CREAT|O_RDWR)) < 0) {
  # else
 -          if ((fd = open(fq_record, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
 +        if ((fd = open(fq_record, O_CREAT|O_RDWR, S_IREAD|S_IWRITE)) < 0) {
  # endif
 -      raw_printf("Warning: cannot write record %s", tmp);
 -              wait_synch();
 -          } else
 +    raw_printf("Warning: cannot write record %s", tmp);
 +        wait_synch();
 +        } else
-         (void) close(fd);
+               (void) nhclose(fd);
 -      } else          /* open succeeded */
 +    } else            /* open succeeded */
-         (void) close(fd);
+           (void) nhclose(fd);
  #else /* MICRO || WIN32*/
  
  # ifdef MAC
@@@ -3032,183 -3043,183 +3041,183 @@@ const char *reason;       /* explanation *
  boolean
  recover_savefile()
  {
 -      int gfd, lfd, sfd;
 -      int lev, savelev, hpid, pltmpsiz;
 -      xchar levc;
 -      struct version_info version_data;
 -      int processed[256];
 -      char savename[SAVESIZE], errbuf[BUFSZ];
 -      struct savefile_info sfi;
 -      char tmpplbuf[PL_NSIZ];
 -
 -      for (lev = 0; lev < 256; lev++)
 -              processed[lev] = 0;
 -
 -      /* level 0 file contains:
 -       *      pid of creating process (ignored here)
 -       *      level number for current level of save file
 -       *      name of save file nethack would have created
 -       *      savefile info
 -       *      player name
 -       *      and game state
 -       */
 -      gfd = open_levelfile(0, errbuf);
 -      if (gfd < 0) {
 -          raw_printf("%s\n", errbuf);
 -          return FALSE;
 -      }
 -      if (read(gfd, (genericptr_t) &hpid, sizeof hpid) != sizeof hpid) {
 -          raw_printf(
 +    int gfd, lfd, sfd;
 +    int lev, savelev, hpid, pltmpsiz;
 +    xchar levc;
 +    struct version_info version_data;
 +    int processed[256];
 +    char savename[SAVESIZE], errbuf[BUFSZ];
 +    struct savefile_info sfi;
 +    char tmpplbuf[PL_NSIZ];
 +
 +    for (lev = 0; lev < 256; lev++)
 +        processed[lev] = 0;
 +
 +    /* level 0 file contains:
 +     *        pid of creating process (ignored here)
 +     *        level number for current level of save file
 +     *        name of save file nethack would have created
 +     *        savefile info
 +     *        player name
 +     *        and game state
 +     */
 +    gfd = open_levelfile(0, errbuf);
 +    if (gfd < 0) {
 +        raw_printf("%s\n", errbuf);
 +        return FALSE;
 +    }
 +    if (read(gfd, (genericptr_t) &hpid, sizeof hpid) != sizeof hpid) {
 +        raw_printf(
  "\nCheckpoint data incompletely written or subsequently clobbered. Recovery impossible.");
-         (void)close(gfd);
+           (void)nhclose(gfd);
 -          return FALSE;
 -      }
 -      if (read(gfd, (genericptr_t) &savelev, sizeof(savelev))
 -                                                      != sizeof(savelev)) {
 -          raw_printf("\nCheckpointing was not in effect for %s -- recovery impossible.\n",
 -                      lock);
 +        return FALSE;
 +    }
 +    if (read(gfd, (genericptr_t) &savelev, sizeof(savelev))
 +                            != sizeof(savelev)) {
 +        raw_printf("\nCheckpointing was not in effect for %s -- recovery impossible.\n",
 +            lock);
-         (void)close(gfd);
+           (void)nhclose(gfd);
 -          return FALSE;
 -      }
 -      if ((read(gfd, (genericptr_t) savename, sizeof savename)
 -              != sizeof savename) ||
 -          (read(gfd, (genericptr_t) &version_data, sizeof version_data)
 -              != sizeof version_data) ||
 -          (read(gfd, (genericptr_t) &sfi, sizeof sfi)
 -              != sizeof sfi) ||
 -          (read(gfd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
 -              != sizeof pltmpsiz) || (pltmpsiz > PL_NSIZ) || 
 -          (read(gfd, (genericptr_t) &tmpplbuf, pltmpsiz)
 -              != pltmpsiz)) {
 -          raw_printf("\nError reading %s -- can't recover.\n", lock);
 +        return FALSE;
 +    }
 +    if ((read(gfd, (genericptr_t) savename, sizeof savename)
 +        != sizeof savename) ||
 +        (read(gfd, (genericptr_t) &version_data, sizeof version_data)
 +        != sizeof version_data) ||
 +        (read(gfd, (genericptr_t) &sfi, sizeof sfi)
 +        != sizeof sfi) ||
 +        (read(gfd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
 +        != sizeof pltmpsiz) || (pltmpsiz > PL_NSIZ) || 
 +        (read(gfd, (genericptr_t) &tmpplbuf, pltmpsiz)
 +        != pltmpsiz)) {
 +        raw_printf("\nError reading %s -- can't recover.\n", lock);
-         (void)close(gfd);
+           (void)nhclose(gfd);
 -          return FALSE;
 -      }
 -
 -      /* save file should contain:
 -       *      version info
 -       *      savefile info
 -       *      player name
 -       *      current level (including pets)
 -       *      (non-level-based) game state
 -       *      other levels
 -       */
 -      set_savefile_name(TRUE);
 -      sfd = create_savefile();
 -      if (sfd < 0) {
 -          raw_printf("\nCannot recover savefile %s.\n", SAVEF);
 +        return FALSE;
 +    }
 +
 +    /* save file should contain:
 +     *        version info
 +     *        savefile info
 +     *        player name
 +     *        current level (including pets)
 +     *        (non-level-based) game state
 +     *        other levels
 +     */
 +    set_savefile_name(TRUE);
 +    sfd = create_savefile();
 +    if (sfd < 0) {
 +        raw_printf("\nCannot recover savefile %s.\n", SAVEF);
-         (void)close(gfd);
+           (void)nhclose(gfd);
 -          return FALSE;
 -      }
 +        return FALSE;
 +    }
  
 -      lfd = open_levelfile(savelev, errbuf);
 -      if (lfd < 0) {
 -          raw_printf("\n%s\n", errbuf);
 +    lfd = open_levelfile(savelev, errbuf);
 +    if (lfd < 0) {
 +        raw_printf("\n%s\n", errbuf);
-         (void)close(gfd);
-         (void)close(sfd);
+           (void)nhclose(gfd);
+           (void)nhclose(sfd);
 -          delete_savefile();
 -          return FALSE;
 -      }
 +        delete_savefile();
 +        return FALSE;
 +    }
  
 -      if (write(sfd, (genericptr_t) &version_data, sizeof version_data)
 -              != sizeof version_data) {
 -          raw_printf("\nError writing %s; recovery failed.", SAVEF);
 +    if (write(sfd, (genericptr_t) &version_data, sizeof version_data)
 +        != sizeof version_data) {
 +        raw_printf("\nError writing %s; recovery failed.", SAVEF);
-         (void)close(gfd);
-         (void)close(sfd);
+           (void)nhclose(gfd);
+           (void)nhclose(sfd);
 -          delete_savefile();
 -          return FALSE;
 -      }
 -
 -      if (write(sfd, (genericptr_t) &sfi, sizeof sfi)
 -              != sizeof sfi) {
 -          raw_printf(
 -                  "\nError writing %s; recovery failed (savefile_info).\n",
 -                  SAVEF);
 +        delete_savefile();
 +        return FALSE;
 +    }
 +
 +    if (write(sfd, (genericptr_t) &sfi, sizeof sfi)
 +        != sizeof sfi) {
 +        raw_printf(
 +            "\nError writing %s; recovery failed (savefile_info).\n",
 +            SAVEF);
-         (void)close(gfd);
-         (void)close(sfd);
+           (void)nhclose(gfd);
+           (void)nhclose(sfd);
 -          delete_savefile();
 -          return FALSE;
 -      }
 -
 -      if (write(sfd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
 -              != sizeof pltmpsiz) {
 -          raw_printf(
 -                  "Error writing %s; recovery failed (player name size).\n",
 -                  SAVEF);
 +        delete_savefile();
 +        return FALSE;
 +    }
 +
 +    if (write(sfd, (genericptr_t) &pltmpsiz, sizeof pltmpsiz)
 +        != sizeof pltmpsiz) {
 +        raw_printf(
 +            "Error writing %s; recovery failed (player name size).\n",
 +            SAVEF);
-         (void)close(gfd);
-         (void)close(sfd);
+           (void)nhclose(gfd);
+           (void)nhclose(sfd);
 -          delete_savefile();
 -          return FALSE;
 -      }
 -
 -      if (write(sfd, (genericptr_t) &tmpplbuf, pltmpsiz)
 -              != pltmpsiz) {
 -          raw_printf(
 -                  "Error writing %s; recovery failed (player name).\n",
 -                  SAVEF);
 +        delete_savefile();
 +        return FALSE;
 +    }
 +
 +    if (write(sfd, (genericptr_t) &tmpplbuf, pltmpsiz)
 +        != pltmpsiz) {
 +        raw_printf(
 +            "Error writing %s; recovery failed (player name).\n",
 +            SAVEF);
-         (void)close(gfd);
-         (void)close(sfd);
+           (void)nhclose(gfd);
+           (void)nhclose(sfd);
 -          delete_savefile();
 -          return FALSE;
 -      }
 +        delete_savefile();
 +        return FALSE;
 +    }
  
 -      if (!copy_bytes(lfd, sfd)) {
 +    if (!copy_bytes(lfd, sfd)) {
-         (void) close(lfd);
-         (void) close(sfd);
+               (void) nhclose(lfd);
+               (void) nhclose(sfd);
 -              delete_savefile();
 -              return FALSE;
 -      }
 +        delete_savefile();
 +        return FALSE;
 +    }
-     (void)close(lfd);
+       (void)nhclose(lfd);
 -      processed[savelev] = 1;
 +    processed[savelev] = 1;
  
 -      if (!copy_bytes(gfd, sfd)) {
 +    if (!copy_bytes(gfd, sfd)) {
-         (void) close(lfd);
-         (void) close(sfd);
+               (void) nhclose(lfd);
+               (void) nhclose(sfd);
 -              delete_savefile();
 -              return FALSE;
 -      }
 +        delete_savefile();
 +        return FALSE;
 +    }
-     (void)close(gfd);
+       (void)nhclose(gfd);
 -      processed[0] = 1;
 -
 -      for (lev = 1; lev < 256; lev++) {
 -              /* level numbers are kept in xchars in save.c, so the
 -               * maximum level number (for the endlevel) must be < 256
 -               */
 -              if (lev != savelev) {
 -                      lfd = open_levelfile(lev, (char *)0);
 -                      if (lfd >= 0) {
 -                              /* any or all of these may not exist */
 -                              levc = (xchar) lev;
 -                              write(sfd, (genericptr_t) &levc, sizeof(levc));
 -                              if (!copy_bytes(lfd, sfd)) {
 +    processed[0] = 1;
 +
 +    for (lev = 1; lev < 256; lev++) {
 +        /* level numbers are kept in xchars in save.c, so the
 +         * maximum level number (for the endlevel) must be < 256
 +         */
 +        if (lev != savelev) {
 +            lfd = open_levelfile(lev, (char *)0);
 +            if (lfd >= 0) {
 +                /* any or all of these may not exist */
 +                levc = (xchar) lev;
 +                write(sfd, (genericptr_t) &levc, sizeof(levc));
 +                if (!copy_bytes(lfd, sfd)) {
-                     (void) close(lfd);
-                     (void) close(sfd);
+                                       (void) nhclose(lfd);
+                                       (void) nhclose(sfd);
 -                                      delete_savefile();
 -                                      return FALSE;
 -                              }
 +                    delete_savefile();
 +                    return FALSE;
 +                }
-                 (void)close(lfd);
+                               (void)nhclose(lfd);
 -                              processed[lev] = 1;
 -                      }
 -              }
 -      }
 +                processed[lev] = 1;
 +            }
 +        }
 +    }
-     (void)close(sfd);
+       (void)nhclose(sfd);
  
  #ifdef HOLD_LOCKFILE_OPEN
 -      really_close();
 -#endif
 -      /*
 -       * We have a successful savefile!
 -       * Only now do we erase the level files.
 -       */
 -      for (lev = 0; lev < 256; lev++) {
 -              if (processed[lev]) {
 -                      const char *fq_lock;
 -                      set_levelfile_name(lock, lev);
 -                      fq_lock = fqname(lock, LEVELPREFIX, 3);
 -                      (void) unlink(fq_lock);
 -              }
 -      }
 -      return TRUE;
 +    really_close();
 +#endif
 +    /*
 +     * We have a successful savefile!
 +     * Only now do we erase the level files.
 +     */
 +    for (lev = 0; lev < 256; lev++) {
 +        if (processed[lev]) {
 +            const char *fq_lock;
 +            set_levelfile_name(lock, lev);
 +            fq_lock = fqname(lock, LEVELPREFIX, 3);
 +            (void) unlink(fq_lock);
 +        }
 +    }
 +    return TRUE;
  }
  
  boolean
diff --cc src/invent.c
index c3ded6dffab51ab927c17c49e54aeb6400cba21c,778d992890c5ab9c28e74e4e2e39da8bec8da126..9e40416031877d0403b71e47fc944f45c5f4d9f1
@@@ -1723,109 -1797,123 +1806,123 @@@ register const char *lets
  boolean want_reply;
  long* out_cnt;
  {
 -      struct obj *otmp;
 -      char ilet, ret;
 -      char *invlet = flags.inv_order;
 +    struct obj *otmp;
 +    char ilet, ret;
 +    char *invlet = flags.inv_order;
-     int n, classcount;
+       int i, n, classcount;
 -      winid win;                              /* windows being used */
 -      static winid local_win = WIN_ERR;       /* window for partial menus */
 -      anything any;
 -      menu_item *selected;
 +    winid win;                                /* windows being used */
 +    static winid local_win = WIN_ERR; /* window for partial menus */
 +    anything any;
 +    menu_item *selected;
+       struct obj **oarray;
  
 -      /* overriden by global flag */
 -      if (flags.perm_invent) {
 -          win = (lets && *lets) ? local_win : WIN_INVEN;
 -          /* create the first time used */
 -          if (win == WIN_ERR)
 -              win = local_win = create_nhwindow(NHW_MENU);
 -      } else
 -          win = WIN_INVEN;
 -
 -      /*
 -      Exit early if no inventory -- but keep going if we are doing
 -      a permanent inventory update.  We need to keep going so the
 -      permanent inventory window updates itself to remove the last
 -      item(s) dropped.  One down side:  the addition of the exception
 -      for permanent inventory window updates _can_ pop the window
 -      up when it's not displayed -- even if it's empty -- because we
 -      don't know at this level if its up or not.  This may not be
 -      an issue if empty checks are done before hand and the call
 -      to here is short circuited away.
 -      */
 -      if (!invent && !(flags.perm_invent && !lets && !want_reply)) {
 -          pline("Not carrying anything.");
 -          return 0;
 -      }
 +    /* overriden by global flag */
 +    if (flags.perm_invent) {
 +        win = (lets && *lets) ? local_win : WIN_INVEN;
 +        /* create the first time used */
 +        if (win == WIN_ERR)
 +        win = local_win = create_nhwindow(NHW_MENU);
 +    } else
 +        win = WIN_INVEN;
  
 -      /* oxymoron? temporarily assign permanent inventory letters */
 -      if (!flags.invlet_constant) reassign();
 -
 -      if (lets && strlen(lets) == 1 && !iflags.override_ID) {
 -          /* when only one item of interest, use pline instead of menus;
 -             we actually use a fake message-line menu in order to allow
 -             the user to perform selection at the --More-- prompt for tty */
 -          ret = '\0';
 -          for (otmp = invent; otmp; otmp = otmp->nobj) {
 -              if (otmp->invlet == lets[0]) {
 -                  ret = message_menu(lets[0],
 -                        want_reply ? PICK_ONE : PICK_NONE,
 -                        xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L));
 -                  if (out_cnt) *out_cnt = -1L;        /* select all */
 -                  break;
 -              }
 -          }
 -          return ret;
 -      }
 +    /*
 +    Exit early if no inventory -- but keep going if we are doing
 +    a permanent inventory update.  We need to keep going so the
 +    permanent inventory window updates itself to remove the last
 +    item(s) dropped.  One down side:  the addition of the exception
 +    for permanent inventory window updates _can_ pop the window
 +    up when it's not displayed -- even if it's empty -- because we
 +    don't know at this level if its up or not.  This may not be
 +    an issue if empty checks are done before hand and the call
 +    to here is short circuited away.
 +    */
 +    if (!invent && !(flags.perm_invent && !lets && !want_reply)) {
 +        pline("Not carrying anything.");
 +        return 0;
 +    }
 +
 +    /* oxymoron? temporarily assign permanent inventory letters */
 +    if (!flags.invlet_constant) reassign();
 +
 +    if (lets && strlen(lets) == 1 && !iflags.override_ID) {
 +        /* when only one item of interest, use pline instead of menus;
 +           we actually use a fake message-line menu in order to allow
 +           the user to perform selection at the --More-- prompt for tty */
 +        ret = '\0';
 +        for (otmp = invent; otmp; otmp = otmp->nobj) {
 +        if (otmp->invlet == lets[0]) {
 +            ret = message_menu(lets[0],
 +              want_reply ? PICK_ONE : PICK_NONE,
 +              xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L));
 +            if (out_cnt) *out_cnt = -1L;      /* select all */
 +            break;
 +        }
 +        }
 +        return ret;
 +    }
  
 -      start_menu(win);
 -      if (wizard && iflags.override_ID) {
 -              char prompt[BUFSZ];
 -              any.a_char = -1;
 -              /* wiz_identify stuffed the wiz_identify cmd character
 -                 into iflags.override_ID */
 -              Sprintf(prompt, "Debug Identify (%s to permanently identify)",
 -                              visctrl(iflags.override_ID));
 -              add_menu(win, NO_GLYPH, &any,' ', iflags.override_ID, ATR_NONE,
 -                              prompt, MENU_UNSELECTED);
 -      }
+       /* count the number of items */
+       for (n = 0, otmp = invent; otmp; otmp = otmp->nobj)
+           if (!lets || !*lets || index(lets, otmp->invlet)) n++;
+       oarray = objarr_init(n);
+       /* Add objects to the array */
+       i = 0;
+       for (otmp = invent; otmp; otmp = otmp->nobj)
+           if (!lets || !*lets || index(lets, otmp->invlet)) {
+               objarr_set(otmp, i++, oarray, (flags.sortloot == 'f'));
+           }
 +    start_menu(win);
 +    if (wizard && iflags.override_ID) {
 +        char prompt[BUFSZ];
 +        any.a_char = -1;
 +        /* wiz_identify stuffed the wiz_identify cmd character
 +           into iflags.override_ID */
 +        Sprintf(prompt, "Debug Identify (%s to permanently identify)",
 +                visctrl(iflags.override_ID));
 +        add_menu(win, NO_GLYPH, &any,' ', iflags.override_ID, ATR_NONE,
 +                prompt, MENU_UNSELECTED);
 +    }
  nextclass:
 -      classcount = 0;
 -      any = zeroany;          /* set all bits to zero */
 +    classcount = 0;
 +    any = zeroany;            /* set all bits to zero */
-     for(otmp = invent; otmp; otmp = otmp->nobj) {
-         ilet = otmp->invlet;
-         if(!lets || !*lets || index(lets, ilet)) {
-             any = zeroany;            /* zero */
-             if (!flags.sortpack || otmp->oclass == *invlet) {
-                 if (flags.sortpack && !classcount) {
-                 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+       for(i = 0; i < n; i++) {
+           otmp = oarray[i];
+           ilet = otmp->invlet;
+           any = zeroany;              /* zero */
+           if (!flags.sortpack || otmp->oclass == *invlet) {
+               if (flags.sortpack && !classcount) {
+                   add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
                                         let_to_name(*invlet, FALSE, (want_reply && iflags.menu_head_objsym)), MENU_UNSELECTED);
-                 classcount++;
-                 }
-                 any.a_char = ilet;
-                 add_menu(win, obj_to_glyph(otmp),
-                     &any, ilet, 0, ATR_NONE, doname(otmp),
-                     MENU_UNSELECTED);
-             }
-         }
-     }
+                   classcount++;
+               }
+               any.a_char = ilet;
+               add_menu(win, obj_to_glyph(otmp),
+                        &any, ilet, 0, ATR_NONE, doname(otmp),
+                        MENU_UNSELECTED);
+           }
+       }
 -      if (flags.sortpack) {
 -              if (*++invlet) goto nextclass;
 -              if (--invlet != venom_inv) {
 -                      invlet = venom_inv;
 -                      goto nextclass;
 -              }
 -      }
 +    if (flags.sortpack) {
 +        if (*++invlet) goto nextclass;
 +        if (--invlet != venom_inv) {
 +            invlet = venom_inv;
 +            goto nextclass;
 +        }
 +    }
+       free(oarray);
 -      end_menu(win, (char *) 0);
 +    end_menu(win, (char *) 0);
  
 -      n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
 -      if (n > 0) {
 -          ret = selected[0].item.a_char;
 -          if (out_cnt) *out_cnt = selected[0].count;
 -          free((genericptr_t)selected);
 -      } else
 -          ret = !n ? '\0' : '\033';   /* cancelled */
 +    n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
 +    if (n > 0) {
 +        ret = selected[0].item.a_char;
 +        if (out_cnt) *out_cnt = selected[0].count;
 +        free((genericptr_t)selected);
 +    } else
 +        ret = !n ? '\0' : '\033';     /* cancelled */
  
 -      return ret;
 +    return ret;
  }
  
  /*
diff --cc src/monst.c
Simple merge
diff --cc src/objnam.c
index 91d29cababb760523020c1389b9028daf0df18ae,25165a4b3c211c831f0d4f8eac7cf77e39bcd8b2..a0db8c6817c502fdd25c9b13d796e90ade2ae2cb
@@@ -16,12 -17,14 +16,14 @@@ STATIC_DCL void FDECL(releaseobuf, (cha
  STATIC_DCL char *FDECL(minimal_xname, (struct obj *));
  STATIC_DCL void FDECL(add_erosion_words, (struct obj *, char *));
  STATIC_DCL boolean FDECL(singplur_lookup, (char *,char *,BOOLEAN_P,
 -                                         const char *const *));
 +                       const char *const *));
  STATIC_DCL char *FDECL(singplur_compound, (char *));
+ STATIC_DCL char *FDECL(xname_flags, (struct obj *, unsigned));
  
  struct Jitem {
 -      int item;
 -      const char *name;
 +    int item;
 +    const char *name;
  };
  
  #define BSTRCMPI(base,ptr,str)            ((ptr) < base || strcmpi((ptr),str))
@@@ -236,265 -239,265 +238,273 @@@ boolean juice;       /* whether or not to app
  
  char *
  xname(obj)
+ struct obj *obj;
+ {
+     return xname_flags(obj, CXN_NORMAL);
+ }
+ char *
+ xname_flags(obj, cxn_flags)
  register struct obj *obj;
+ unsigned cxn_flags;   /* bitmask of CXN_xxx values */
  {
 -      register char *buf;
 -      register int typ = obj->otyp;
 -      register struct objclass *ocl = &objects[typ];
 -      int nn = ocl->oc_name_known, omndx = obj->corpsenm;
 -      const char *actualn = OBJ_NAME(*ocl);
 -      const char *dn = OBJ_DESCR(*ocl);
 -      const char *un = ocl->oc_uname;
 +    register char *buf;
 +    register int typ = obj->otyp;
 +    register struct objclass *ocl = &objects[typ];
 +    int nn = ocl->oc_name_known, omndx = obj->corpsenm;
 +    const char *actualn = OBJ_NAME(*ocl);
 +    const char *dn = OBJ_DESCR(*ocl);
 +    const char *un = ocl->oc_uname;
-     boolean pluralize = (obj->quan != 1L);
+       boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
 -      boolean known, dknown, bknown;
 -
 -      buf = nextobuf() + PREFIX;      /* leave room for "17 -3 " */
 -      if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
 -              actualn = Japanese_item_name(typ);
 -
 -      buf[0] = '\0';
 -      /*
 -       * clean up known when it's tied to oc_name_known, eg after AD_DRIN
 -       * This is only required for unique objects since the article
 -       * printed for the object is tied to the combination of the two
 -       * and printing the wrong article gives away information.
 -       */
 -      if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
 -      if (!Blind) obj->dknown = TRUE;
 -      if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
 +    boolean known, dknown, bknown;
  
 -      if (iflags.override_ID) {
 -              known = dknown = bknown = TRUE;
 -              nn = 1;
 -      } else {
 -              known = obj->known;
 -              dknown = obj->dknown;
 -              bknown = obj->bknown;
 -      }
 +    buf = nextobuf() + PREFIX;        /* leave room for "17 -3 " */
 +    if (Role_if(PM_SAMURAI) && Japanese_item_name(typ))
 +        actualn = Japanese_item_name(typ);
  
 -      if (obj_is_pname(obj))
 -          goto nameit;
 -      switch (obj->oclass) {
 -          case AMULET_CLASS:
 -              if (!dknown)
 -                      Strcpy(buf, "amulet");
 -              else if (typ == AMULET_OF_YENDOR ||
 -                       typ == FAKE_AMULET_OF_YENDOR)
 -                      /* each must be identified individually */
 -                      Strcpy(buf, known ? actualn : dn);
 -              else if (nn)
 -                      Strcpy(buf, actualn);
 -              else if (un)
 -                      Sprintf(buf,"amulet called %s", un);
 -              else
 -                      Sprintf(buf,"%s amulet", dn);
 -              break;
 -          case WEAPON_CLASS:
 -              if (is_poisonable(obj) && obj->opoisoned)
 -                      Strcpy(buf, "poisoned ");
 -          case VENOM_CLASS:
 -          case TOOL_CLASS:
 -              if (typ == LENSES)
 -                      Strcpy(buf, "pair of ");
 -
 -              if (!dknown)
 -                      Strcat(buf, dn ? dn : actualn);
 -              else if (nn)
 -                      Strcat(buf, actualn);
 -              else if (un) {
 -                      Strcat(buf, dn ? dn : actualn);
 -                      Strcat(buf, " called ");
 -                      Strcat(buf, un);
 -              } else
 -                      Strcat(buf, dn ? dn : actualn);
 -              /* If we use an() here we'd have to remember never to use */
 -              /* it whenever calling doname() or xname(). */
 -              if (typ == FIGURINE && omndx != NON_PM)
 -                  Sprintf(eos(buf), " of a%s %s",
 -                          index(vowels, *mons[omndx].mname) ? "n" : "",
 -                          mons[omndx].mname);
 -              break;
 -          case ARMOR_CLASS:
 -              /* depends on order of the dragon scales objects */
 -              if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
 -                      Sprintf(buf, "set of %s", actualn);
 -                      break;
 -              }
 -              if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
 -
 -              if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
 -                              && !dknown) {
 -                      Strcpy(buf, "shield");
 -                      break;
 -              }
 -              if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
 -                      Strcpy(buf, "smooth shield");
 -                      break;
 -              }
 -
 -              if(nn)  Strcat(buf, actualn);
 -              else if(un) {
 -                      if(is_boots(obj))
 -                              Strcat(buf,"boots");
 -                      else if(is_gloves(obj))
 -                              Strcat(buf,"gloves");
 -                      else if(is_cloak(obj))
 -                              Strcpy(buf,"cloak");
 -                      else if(is_helmet(obj))
 -                              Strcpy(buf,"helmet");
 -                      else if(is_shield(obj))
 -                              Strcpy(buf,"shield");
 -                      else
 -                              Strcpy(buf,"armor");
 -                      Strcat(buf, " called ");
 -                      Strcat(buf, un);
 -              } else  Strcat(buf, dn);
 -              break;
 -          case FOOD_CLASS:
 -              if (typ == SLIME_MOLD) {
 -                      register struct fruit *f;
 -
 -                      for(f=ffruit; f; f = f->nextf) {
 -                              if(f->fid == obj->spe) {
 -                                      Strcpy(buf, f->fname);
 -                                      break;
 -                              }
 -                      }
 -                      if (!f) {
 -                          impossible("Bad fruit #%d?", obj->spe);
 -                          Strcpy(buf, "fruit");
 -                      } else if (pluralize) {
 -                          /* ick; already pluralized fruit names
 -                             are allowed--we want to try to avoid
 -                             adding a redundant plural suffix */
 -                          Strcpy(buf, makeplural(makesingular(buf)));
 -                          pluralize = FALSE;
 -                      }
 -                      break;
 -              }
 -
 -              Strcpy(buf, actualn);
 -              if (typ == TIN && known)
 -                      tin_details(obj, omndx, buf);
 -              break;
 -          case COIN_CLASS:
 -          case CHAIN_CLASS:
 -              Strcpy(buf, actualn);
 -              break;
 -          case ROCK_CLASS:
 -              if (typ == STATUE && omndx != NON_PM)
 -                  Sprintf(buf, "%s%s of %s%s",
 -                      (Role_if(PM_ARCHEOLOGIST) &&
 -                          (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
 -                      actualn,
 -                      type_is_pname(&mons[omndx]) ? "" :
 -                        the_unique_pm(&mons[omndx]) ? "the " :
 -                          index(vowels, *mons[omndx].mname) ? "an " : "a ",
 -                      mons[omndx].mname);
 -              else Strcpy(buf, actualn);
 -              break;
 -          case BALL_CLASS:
 -              Sprintf(buf, "%sheavy iron ball",
 -                      (obj->owt > ocl->oc_weight) ? "very " : "");
 -              break;
 -          case POTION_CLASS:
 -              if (dknown && obj->odiluted)
 -                      Strcpy(buf, "diluted ");
 -              if(nn || un || !dknown) {
 -                      Strcat(buf, "potion");
 -                      if(!dknown) break;
 -                      if(nn) {
 -                          Strcat(buf, " of ");
 -                          if (typ == POT_WATER &&
 -                              bknown && (obj->blessed || obj->cursed)) {
 -                              Strcat(buf, obj->blessed ? "holy " : "unholy ");
 -                          }
 -                          Strcat(buf, actualn);
 -                      } else {
 -                              Strcat(buf, " called ");
 -                              Strcat(buf, un);
 -                      }
 -              } else {
 -                      Strcat(buf, dn);
 -                      Strcat(buf, " potion");
 -              }
 -              break;
 -      case SCROLL_CLASS:
 -              Strcpy(buf, "scroll");
 -              if(!dknown) break;
 -              if(nn) {
 -                      Strcat(buf, " of ");
 -                      Strcat(buf, actualn);
 -              } else if(un) {
 -                      Strcat(buf, " called ");
 -                      Strcat(buf, un);
 -              } else if (ocl->oc_magic) {
 -                      Strcat(buf, " labeled ");
 -                      Strcat(buf, dn);
 -              } else {
 -                      Strcpy(buf, dn);
 -                      Strcat(buf, " scroll");
 -              }
 -              break;
 -      case WAND_CLASS:
 -              if(!dknown)
 -                      Strcpy(buf, "wand");
 -              else if(nn)
 -                      Sprintf(buf, "wand of %s", actualn);
 -              else if(un)
 -                      Sprintf(buf, "wand called %s", un);
 -              else
 -                      Sprintf(buf, "%s wand", dn);
 -              break;
 -      case SPBOOK_CLASS:
 -              if (!dknown) {
 -                      Strcpy(buf, "spellbook");
 -              } else if (nn) {
 -                      if (typ != SPE_BOOK_OF_THE_DEAD)
 -                          Strcpy(buf, "spellbook of ");
 -                      Strcat(buf, actualn);
 -              } else if (un) {
 -                      Sprintf(buf, "spellbook called %s", un);
 -              } else
 -                      Sprintf(buf, "%s spellbook", dn);
 -              break;
 -      case RING_CLASS:
 -              if(!dknown)
 -                      Strcpy(buf, "ring");
 -              else if(nn)
 -                      Sprintf(buf, "ring of %s", actualn);
 -              else if(un)
 -                      Sprintf(buf, "ring called %s", un);
 -              else
 -                      Sprintf(buf, "%s ring", dn);
 -              break;
 -      case GEM_CLASS:
 -          {
 -              const char *rock =
 -                          (ocl->oc_material == MINERAL) ? "stone" : "gem";
 -              if (!dknown) {
 -                  Strcpy(buf, rock);
 -              } else if (!nn) {
 -                  if (un) Sprintf(buf,"%s called %s", rock, un);
 -                  else Sprintf(buf, "%s %s", dn, rock);
 -              } else {
 -                  Strcpy(buf, actualn);
 -                  if (GemStone(typ)) Strcat(buf, " stone");
 -              }
 -              break;
 -          }
 -      default:
 -              Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
 -      }
 -      if (pluralize) Strcpy(buf, makeplural(buf));
 +    buf[0] = '\0';
 +    /*
 +     * clean up known when it's tied to oc_name_known, eg after AD_DRIN
 +     * This is only required for unique objects since the article
 +     * printed for the object is tied to the combination of the two
 +     * and printing the wrong article gives away information.
 +     */
 +    if (!nn && ocl->oc_uses_known && ocl->oc_unique) obj->known = 0;
 +    if (!Blind) obj->dknown = TRUE;
 +    if (Role_if(PM_PRIEST)) obj->bknown = TRUE;
 +
 +    if (iflags.override_ID) {
 +        known = dknown = bknown = TRUE;
 +        nn = 1;
 +    } else {
 +        known = obj->known;
 +        dknown = obj->dknown;
 +        bknown = obj->bknown;
 +    }
 +
 +    if (obj_is_pname(obj))
 +        goto nameit;
 +    switch (obj->oclass) {
 +        case AMULET_CLASS:
 +        if (!dknown)
 +            Strcpy(buf, "amulet");
 +        else if (typ == AMULET_OF_YENDOR ||
 +             typ == FAKE_AMULET_OF_YENDOR)
 +            /* each must be identified individually */
 +            Strcpy(buf, known ? actualn : dn);
 +        else if (nn)
 +            Strcpy(buf, actualn);
 +        else if (un)
 +            Sprintf(buf,"amulet called %s", un);
 +        else
 +            Sprintf(buf,"%s amulet", dn);
 +        break;
 +        case WEAPON_CLASS:
 +        if (is_poisonable(obj) && obj->opoisoned)
 +            Strcpy(buf, "poisoned ");
 +        case VENOM_CLASS:
 +        case TOOL_CLASS:
 +        if (typ == LENSES)
 +            Strcpy(buf, "pair of ");
 +
 +        if (!dknown)
 +            Strcat(buf, dn ? dn : actualn);
 +        else if (nn)
 +            Strcat(buf, actualn);
 +        else if (un) {
 +            Strcat(buf, dn ? dn : actualn);
 +            Strcat(buf, " called ");
 +            Strcat(buf, un);
 +        } else
 +            Strcat(buf, dn ? dn : actualn);
 +        /* If we use an() here we'd have to remember never to use */
 +        /* it whenever calling doname() or xname(). */
 +        if (typ == FIGURINE && omndx != NON_PM)
 +            Sprintf(eos(buf), " of a%s %s",
 +                index(vowels, *mons[omndx].mname) ? "n" : "",
 +                mons[omndx].mname);
 +        break;
 +        case ARMOR_CLASS:
 +        /* depends on order of the dragon scales objects */
 +        if (typ >= GRAY_DRAGON_SCALES && typ <= YELLOW_DRAGON_SCALES) {
 +            Sprintf(buf, "set of %s", actualn);
 +            break;
 +        }
 +        if(is_boots(obj) || is_gloves(obj)) Strcpy(buf,"pair of ");
 +
 +        if(obj->otyp >= ELVEN_SHIELD && obj->otyp <= ORCISH_SHIELD
 +                && !dknown) {
 +            Strcpy(buf, "shield");
 +            break;
 +        }
 +        if(obj->otyp == SHIELD_OF_REFLECTION && !dknown) {
 +            Strcpy(buf, "smooth shield");
 +            break;
 +        }
 +
 +        if(nn)        Strcat(buf, actualn);
 +        else if(un) {
 +            if(is_boots(obj))
 +                Strcat(buf,"boots");
 +            else if(is_gloves(obj))
 +                Strcat(buf,"gloves");
 +            else if(is_cloak(obj))
 +                Strcpy(buf,"cloak");
 +            else if(is_helmet(obj))
 +                Strcpy(buf,"helmet");
 +            else if(is_shield(obj))
 +                Strcpy(buf,"shield");
 +            else
 +                Strcpy(buf,"armor");
 +            Strcat(buf, " called ");
 +            Strcat(buf, un);
 +        } else        Strcat(buf, dn);
 +        break;
 +        case FOOD_CLASS:
 +        if (typ == SLIME_MOLD) {
 +            register struct fruit *f;
 +
 +            for(f=ffruit; f; f = f->nextf) {
 +                if(f->fid == obj->spe) {
 +                    Strcpy(buf, f->fname);
 +                    break;
 +                }
 +            }
 +            if (!f) {
 +                impossible("Bad fruit #%d?", obj->spe);
 +                Strcpy(buf, "fruit");
 +            } else if (pluralize) {
 +                /* ick; already pluralized fruit names
 +                   are allowed--we want to try to avoid
 +                   adding a redundant plural suffix */
 +                Strcpy(buf, makeplural(makesingular(buf)));
 +                pluralize = FALSE;
 +            }
 +            break;
 +        }
 +        if (Is_pudding(obj)) {
 +            Sprintf(buf, "%s%s",
 +                        obj->owt < 100 ? "small " 
 +                          : obj->owt > 500 ? "very large "
 +                            : obj->owt > 300 ? "large "
 +                              : "", actualn);
 +            break;
 +        }
 +
 +        Strcpy(buf, actualn);
 +        if (typ == TIN && known)
 +            tin_details(obj, omndx, buf);
 +        break;
 +        case COIN_CLASS:
 +        case CHAIN_CLASS:
 +        Strcpy(buf, actualn);
 +        break;
 +        case ROCK_CLASS:
 +        if (typ == STATUE && omndx != NON_PM)
 +            Sprintf(buf, "%s%s of %s%s",
 +            (Role_if(PM_ARCHEOLOGIST) &&
 +                (obj->spe & STATUE_HISTORIC)) ? "historic " : "",
 +            actualn,
 +            type_is_pname(&mons[omndx]) ? "" :
 +              the_unique_pm(&mons[omndx]) ? "the " :
 +                index(vowels, *mons[omndx].mname) ? "an " : "a ",
 +            mons[omndx].mname);
 +        else Strcpy(buf, actualn);
 +        break;
 +        case BALL_CLASS:
 +        Sprintf(buf, "%sheavy iron ball",
 +            (obj->owt > ocl->oc_weight) ? "very " : "");
 +        break;
 +        case POTION_CLASS:
 +        if (dknown && obj->odiluted)
 +            Strcpy(buf, "diluted ");
 +        if(nn || un || !dknown) {
 +            Strcat(buf, "potion");
 +            if(!dknown) break;
 +            if(nn) {
 +                Strcat(buf, " of ");
 +                if (typ == POT_WATER &&
 +                bknown && (obj->blessed || obj->cursed)) {
 +                Strcat(buf, obj->blessed ? "holy " : "unholy ");
 +                }
 +                Strcat(buf, actualn);
 +            } else {
 +                Strcat(buf, " called ");
 +                Strcat(buf, un);
 +            }
 +        } else {
 +            Strcat(buf, dn);
 +            Strcat(buf, " potion");
 +        }
 +        break;
 +    case SCROLL_CLASS:
 +        Strcpy(buf, "scroll");
 +        if(!dknown) break;
 +        if(nn) {
 +            Strcat(buf, " of ");
 +            Strcat(buf, actualn);
 +        } else if(un) {
 +            Strcat(buf, " called ");
 +            Strcat(buf, un);
 +        } else if (ocl->oc_magic) {
 +            Strcat(buf, " labeled ");
 +            Strcat(buf, dn);
 +        } else {
 +            Strcpy(buf, dn);
 +            Strcat(buf, " scroll");
 +        }
 +        break;
 +    case WAND_CLASS:
 +        if(!dknown)
 +            Strcpy(buf, "wand");
 +        else if(nn)
 +            Sprintf(buf, "wand of %s", actualn);
 +        else if(un)
 +            Sprintf(buf, "wand called %s", un);
 +        else
 +            Sprintf(buf, "%s wand", dn);
 +        break;
 +    case SPBOOK_CLASS:
 +        if (!dknown) {
 +            Strcpy(buf, "spellbook");
 +        } else if (nn) {
 +            if (typ != SPE_BOOK_OF_THE_DEAD)
 +                Strcpy(buf, "spellbook of ");
 +            Strcat(buf, actualn);
 +        } else if (un) {
 +            Sprintf(buf, "spellbook called %s", un);
 +        } else
 +            Sprintf(buf, "%s spellbook", dn);
 +        break;
 +    case RING_CLASS:
 +        if(!dknown)
 +            Strcpy(buf, "ring");
 +        else if(nn)
 +            Sprintf(buf, "ring of %s", actualn);
 +        else if(un)
 +            Sprintf(buf, "ring called %s", un);
 +        else
 +            Sprintf(buf, "%s ring", dn);
 +        break;
 +    case GEM_CLASS:
 +        {
 +        const char *rock =
 +                (ocl->oc_material == MINERAL) ? "stone" : "gem";
 +        if (!dknown) {
 +            Strcpy(buf, rock);
 +        } else if (!nn) {
 +            if (un) Sprintf(buf,"%s called %s", rock, un);
 +            else Sprintf(buf, "%s %s", dn, rock);
 +        } else {
 +            Strcpy(buf, actualn);
 +            if (GemStone(typ)) Strcat(buf, " stone");
 +        }
 +        break;
 +        }
 +    default:
 +        Sprintf(buf,"glorkum %d %d %d", obj->oclass, typ, obj->spe);
 +    }
 +    if (pluralize) Strcpy(buf, makeplural(buf));
  
        if (obj->otyp == T_SHIRT && program_state.gameover) {
            char tmpbuf[BUFSZ];
@@@ -1074,11 -1071,21 +1084,21 @@@ char 
  cxname(obj)
  struct obj *obj;
  {
 -      if (obj->otyp == CORPSE)
 -          return corpse_xname(obj, (const char *)0, CXN_NORMAL);
 -      return xname(obj);
 +    if (obj->otyp == CORPSE)
 +        return corpse_xname(obj, (const char *)0, CXN_NORMAL);
 +    return xname(obj);
  }
  
+ /* like cxname, but ignores quantity */
+ char *
+ cxname_singular(obj)
+ struct obj *obj;
+ {
+       if (obj->otyp == CORPSE)
+           return corpse_xname(obj, (const char *)0, CXN_SINGULAR);
+       return xname_flags(obj, CXN_SINGULAR);
+ }
  /* treat an object as fully ID'd when it might be used as reason for death */
  char *
  killer_xname(obj)
diff --cc src/sp_lev.c
index 54bc575f9d0ef495c4dbd4a9cd8fb0e881aa6930,e23c9887134ef69311b476468cdba0e1b3eb0ccb..5910cf7cde3ed520c0e76717a33ec4622157fdfa
@@@ -4939,9 -5032,10 +5032,10 @@@ sp_lev *lvl
            break;
        case SPO_SEL_LINE:
            {
 -              struct opvar *tmp, *tmp2, *pt = selection_opvar(NULL);
 +              struct opvar *tmp = NULL, *tmp2 = NULL, *pt = selection_opvar(NULL);
                schar x1,y1,x2,y2;
-               if (!OV_pop_c(tmp) || !OV_pop_c(tmp2)) panic("no ter sel linecoord");
+               if (!OV_pop_c(tmp)) panic("no ter sel linecoord1");
+               if (!OV_pop_c(tmp2)) panic("no ter sel linecoord2");
                get_location_coord(&x1, &y1, ANY_LOC, coder->croom, OV_i(tmp));
                get_location_coord(&x2, &y2, ANY_LOC, coder->croom, OV_i(tmp2));
                x1 = (x1 < 0) ? 0 : x1;
            break;
        case SPO_SEL_RNDLINE:
            {
 -              struct opvar *tmp, *tmp2, *tmp3, *pt = selection_opvar(NULL);
 +              struct opvar *tmp = NULL, *tmp2 = NULL, *tmp3, *pt = selection_opvar(NULL);
                schar x1,y1,x2,y2;
-               if (!OV_pop_i(tmp3) || !OV_pop_c(tmp) || !OV_pop_c(tmp2)) panic("no ter sel randline");
+               if (!OV_pop_i(tmp3)) panic("no ter sel randline1");
+               if (!OV_pop_c(tmp)) panic("no ter sel randline2");
+               if (!OV_pop_c(tmp2)) panic("no ter sel randline3");
                get_location_coord(&x1, &y1, ANY_LOC, coder->croom, OV_i(tmp));
                get_location_coord(&x2, &y2, ANY_LOC, coder->croom, OV_i(tmp2));
                x1 = (x1 < 0) ? 0 : x1;
diff --cc src/trap.c
Simple merge
index 0737182c303bab761f8c224b830cd9af169e61e1,e9b3aade096151f391ef845b664d46c1de195180..412b6f9ebf23a96e77d940ccc7aace38859fe137
@@@ -420,97 -393,97 +420,97 @@@ char *argv[]
  # endif
  #endif        /* PC_LOCKING */
  
 -      /* Set up level 0 file to keep the game state.
 -       */
 -      fd = create_levelfile(0, (char *)0);
 -      if (fd < 0) {
 -              raw_print("Cannot create lock file");
 -      } else {
 +    /* Set up level 0 file to keep the game state.
 +     */
 +    fd = create_levelfile(0, (char *)0);
 +    if (fd < 0) {
 +        raw_print("Cannot create lock file");
 +    } else {
  #ifdef WIN32
 -              hackpid = GetCurrentProcessId();
 +        hackpid = GetCurrentProcessId();
  #else
 -              hackpid = 1;
 +        hackpid = 1;
  #endif
 -              write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
 +        write(fd, (genericptr_t) &hackpid, sizeof(hackpid));
-         close(fd);
+               nhclose(fd);
 -      }
 +    }
  #ifdef MFLOPPY
 -      level_info[0].where = ACTIVE;
 +    level_info[0].where = ACTIVE;
  #endif
  
 -      /*
 -       *  Initialize the vision system.  This must be before mklev() on a
 -       *  new game or before a level restore on a saved game.
 -       */
 -      vision_init();
 +    /*
 +     *  Initialize the vision system.  This must be before mklev() on a
 +     *  new game or before a level restore on a saved game.
 +     */
 +    vision_init();
  
 -      display_gamewindows();
 +    display_gamewindows();
  #ifdef WIN32
 -      getreturn_enabled = TRUE;
 +    getreturn_enabled = TRUE;
  #endif
  
 -      /*
 -       * First, try to find and restore a save file for specified character.
 -       * We'll return here if new game player_selection() renames the hero.
 -       */
 +    /*
 +     * First, try to find and restore a save file for specified character.
 +     * We'll return here if new game player_selection() renames the hero.
 +     */
   attempt_restore:
 -      if ((fd = restore_saved_game()) >= 0) {
 +    if ((fd = restore_saved_game()) >= 0) {
  #ifndef NO_SIGNAL
 -              (void) signal(SIGINT, (SIG_RET_TYPE) done1);
 +        (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  #endif
  #ifdef NEWS
 -              if(iflags.news){
 -                  display_file(NEWS, FALSE);
 -                  iflags.news = FALSE;
 -              }
 -#endif
 -              pline("Restoring save file...");
 -              mark_synch();   /* flush output */
 -
 -              if (dorecover(fd)) {
 -                  resuming = TRUE;    /* not starting new game */
 -                  if (discover)
 -                      You("are in non-scoring discovery mode.");
 -                  if (discover || wizard) {
 -                      if(yn("Do you want to keep the save file?") == 'n')
 -                              (void) delete_savefile();
 -                      else {
 -                          nh_compress(fqname(SAVEF, SAVEPREFIX, 0));
 -                      }
 -                  }
 -              }
 -      }
 -
 -      if (!resuming) {
 -              /* new game:  start by choosing role, race, etc;
 -                 player might change the hero's name while doing that,
 -                 in which case we try to restore under the new name
 -                 and skip selection this time if that didn't succeed */
 -              if (!iflags.renameinprogress) {
 -                  player_selection();
 -                  if (iflags.renameinprogress) {
 -                      /* player has renamed the hero while selecting role;
 -                         discard current lock file and create another for
 -                         the new character name */
 +        if(iflags.news){
 +            display_file(NEWS, FALSE);
 +            iflags.news = FALSE;
 +        }
 +#endif
 +        pline("Restoring save file...");
 +        mark_synch(); /* flush output */
 +
 +        if (dorecover(fd)) {
 +            resuming = TRUE;  /* not starting new game */
 +            if (discover)
 +            You("are in non-scoring discovery mode.");
 +            if (discover || wizard) {
 +            if(yn("Do you want to keep the save file?") == 'n')
 +                (void) delete_savefile();
 +            else {
 +                nh_compress(fqname(SAVEF, SAVEPREFIX, 0));
 +            }
 +            }
 +        }
 +    }
 +
 +    if (!resuming) {
 +        /* new game:  start by choosing role, race, etc;
 +           player might change the hero's name while doing that,
 +           in which case we try to restore under the new name
 +           and skip selection this time if that didn't succeed */
 +        if (!iflags.renameinprogress) {
 +            player_selection();
 +            if (iflags.renameinprogress) {
 +            /* player has renamed the hero while selecting role;
 +               discard current lock file and create another for
 +               the new character name */
  #if 0       /* this needs to be reconciled with the getlock mess above... */
 -                      delete_levelfile(0); /* remove empty lock file */
 -                      getlock();
 +            delete_levelfile(0); /* remove empty lock file */
 +            getlock();
  #endif
 -                      goto attempt_restore;
 -                  }
 -              }
 -              newgame();
 -              if (discover)
 -                      You("are in non-scoring discovery mode.");
 -      }
 +            goto attempt_restore;
 +            }
 +        }
 +        newgame();
 +        if (discover)
 +            You("are in non-scoring discovery mode.");
 +    }
  
  #ifndef NO_SIGNAL
 -      (void) signal(SIGINT, SIG_IGN);
 +    (void) signal(SIGINT, SIG_IGN);
  #endif
  #ifdef OS2
 -      gettty(); /* somehow ctrl-P gets turned back on during startup ... */
 +    gettty(); /* somehow ctrl-P gets turned back on during startup ... */
  #endif
 -      return resuming;
 +    return resuming;
  }
  
  STATIC_OVL void