Source:NetHack 3.6.0/src/topten.c

From NetHackWiki
(Redirected from Source:Topten.c)
Jump to: navigation, search

Below is the full text to topten.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/topten.c#line123]], for example.

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

Top of file

  1.  /* NetHack 3.6	topten.c	$NHDT-Date: 1448117546 2015/11/21 14:52:26 $  $NHDT-Branch: master $:$NHDT-Revision: 1.40 $ */
  2.  /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5.  #include "hack.h"
  6.  #include "dlb.h"
  7.  #ifdef SHORT_FILENAMES
  8.  #include "patchlev.h"
  9.  #else
  10.  #include "patchlevel.h"
  11.  #endif
  12.  
  13.  #ifdef VMS
  14.  /* We don't want to rewrite the whole file, because that entails
  15.     creating a new version which requires that the old one be deletable. */
  16.  #define UPDATE_RECORD_IN_PLACE
  17.  #endif
  18.  
  19.  /*
  20.   * Updating in place can leave junk at the end of the file in some
  21.   * circumstances (if it shrinks and the O.S. doesn't have a straightforward
  22.   * way to truncate it).  The trailing junk is harmless and the code
  23.   * which reads the scores will ignore it.
  24.   */
  25.  #ifdef UPDATE_RECORD_IN_PLACE
  26.  static long final_fpos;
  27.  #endif
  28.  
  29.  #define done_stopprint program_state.stopprint
  30.  
  31.  #define newttentry() (struct toptenentry *) alloc(sizeof (struct toptenentry))
  32.  #define dealloc_ttentry(ttent) free((genericptr_t) (ttent))
  33.  #define NAMSZ 10
  34.  #define DTHSZ 100
  35.  #define ROLESZ 3
  36.  
  37.  struct toptenentry {
  38.      struct toptenentry *tt_next;
  39.  #ifdef UPDATE_RECORD_IN_PLACE
  40.      long fpos;
  41.  #endif
  42.      long points;
  43.      int deathdnum, deathlev;
  44.      int maxlvl, hp, maxhp, deaths;
  45.      int ver_major, ver_minor, patchlevel;
  46.      long deathdate, birthdate;
  47.      int uid;
  48.      char plrole[ROLESZ + 1];
  49.      char plrace[ROLESZ + 1];
  50.      char plgend[ROLESZ + 1];
  51.      char plalign[ROLESZ + 1];
  52.      char name[NAMSZ + 1];
  53.      char death[DTHSZ + 1];
  54.  } * tt_head;
  55.  /* size big enough to read in all the string fields at once; includes
  56.     room for separating space or trailing newline plus string terminator */
  57.  #define SCANBUFSZ (4 * (ROLESZ + 1) + (NAMSZ + 1) + (DTHSZ + 1) + 1)
  58.  
  59.  STATIC_DCL void FDECL(topten_print, (const char *));
  60.  STATIC_DCL void FDECL(topten_print_bold, (const char *));
  61.  STATIC_DCL xchar FDECL(observable_depth, (d_level *));
  62.  STATIC_DCL void NDECL(outheader);
  63.  STATIC_DCL void FDECL(outentry, (int, struct toptenentry *, BOOLEAN_P));
  64.  STATIC_DCL void FDECL(discardexcess, (FILE *));
  65.  STATIC_DCL void FDECL(readentry, (FILE *, struct toptenentry *));
  66.  STATIC_DCL void FDECL(writeentry, (FILE *, struct toptenentry *));
  67.  STATIC_DCL void FDECL(writexlentry, (FILE *, struct toptenentry *));
  68.  STATIC_DCL long NDECL(encodexlogflags);
  69.  STATIC_DCL long NDECL(encodeconduct);
  70.  STATIC_DCL long NDECL(encodeachieve);
  71.  STATIC_DCL void FDECL(free_ttlist, (struct toptenentry *));
  72.  STATIC_DCL int FDECL(classmon, (char *, BOOLEAN_P));
  73.  STATIC_DCL int FDECL(score_wanted, (BOOLEAN_P, int, struct toptenentry *, int,
  74.                                      const char **, int));
  75.  #ifdef NO_SCAN_BRACK
  76.  STATIC_DCL void FDECL(nsb_mung_line, (char *));
  77.  STATIC_DCL void FDECL(nsb_unmung_line, (char *));
  78.  #endif
  79.  
  80.  static winid toptenwin = WIN_ERR;
  81.  

formatkiller

  1.  /* "killed by",&c ["an"] 'killer.name' */
  2.  void
  3.  formatkiller(buf, siz, how)
  4.  char *buf;
  5.  unsigned siz;
  6.  int how;
  7.  {
  8.      static NEARDATA const char *const killed_by_prefix[] = {
  9.          /* DIED, CHOKING, POISONING, STARVING, */
  10.          "killed by ", "choked on ", "poisoned by ", "died of ",
  11.          /* DROWNING, BURNING, DISSOLVED, CRUSHING, */
  12.          "drowned in ", "burned by ", "dissolved in ", "crushed to death by ",
  13.          /* STONING, TURNED_SLIME, GENOCIDED, */
  14.          "petrified by ", "turned to slime by ", "killed by ",
  15.          /* PANICKED, TRICKED, QUIT, ESCAPED, ASCENDED */
  16.          "", "", "", "", ""
  17.      };
  18.      unsigned l;
  19.      char *kname = killer.name;
  20.  
  21.      buf[0] = '\0'; /* so strncat() can find the end */
  22.      switch (killer.format) {
  23.      default:
  24.          impossible("bad killer format? (%d)", killer.format);
  25.          /*FALLTHRU*/
  26.      case NO_KILLER_PREFIX:
  27.          break;
  28.      case KILLED_BY_AN:
  29.          kname = an(kname);
  30.          /*FALLTHRU*/
  31.      case KILLED_BY:
  32.          (void) strncat(buf, killed_by_prefix[how], siz - 1);
  33.          l = strlen(buf);
  34.          buf += l, siz -= l;
  35.          break;
  36.      }
  37.      /* we're writing into buf[0] (after possibly advancing buf) rather than
  38.         appending, but strncat() appends a terminator and strncpy() doesn't */
  39.      (void) strncat(buf, kname, siz - 1);
  40.  }
  41.  

topten_print

  1.  STATIC_OVL void
  2.  topten_print(x)
  3.  const char *x;
  4.  {
  5.      if (toptenwin == WIN_ERR)
  6.          raw_print(x);
  7.      else
  8.          putstr(toptenwin, ATR_NONE, x);
  9.  }
  10.  

topten_print_bold

  1.  STATIC_OVL void
  2.  topten_print_bold(x)
  3.  const char *x;
  4.  {
  5.      if (toptenwin == WIN_ERR)
  6.          raw_print_bold(x);
  7.      else
  8.          putstr(toptenwin, ATR_BOLD, x);
  9.  }
  10.  

observable_depth

  1.  STATIC_OVL xchar
  2.  observable_depth(lev)
  3.  d_level *lev;
  4.  {
  5.  #if 0
  6.      /* if we ever randomize the order of the elemental planes, we
  7.         must use a constant external representation in the record file */
  8.      if (In_endgame(lev)) {
  9.          if (Is_astralevel(lev))
  10.              return -5;
  11.          else if (Is_waterlevel(lev))
  12.              return -4;
  13.          else if (Is_firelevel(lev))
  14.              return -3;
  15.          else if (Is_airlevel(lev))
  16.              return -2;
  17.          else if (Is_earthlevel(lev))
  18.              return -1;
  19.          else
  20.              return 0; /* ? */
  21.      } else
  22.  #endif
  23.      return depth(lev);
  24.  }
  25.  

discardexcess

  1.  /* throw away characters until current record has been entirely consumed */
  2.  STATIC_OVL void
  3.  discardexcess(rfile)
  4.  FILE *rfile;
  5.  {
  6.      int c;
  7.  
  8.      do {
  9.          c = fgetc(rfile);
  10.      } while (c != '\n' && c != EOF);
  11.  }
  12.  

readentry

  1.  STATIC_OVL void
  2.  readentry(rfile, tt)
  3.  FILE *rfile;
  4.  struct toptenentry *tt;
  5.  {
  6.      char inbuf[SCANBUFSZ], s1[SCANBUFSZ], s2[SCANBUFSZ], s3[SCANBUFSZ],
  7.          s4[SCANBUFSZ], s5[SCANBUFSZ], s6[SCANBUFSZ];
  8.  
  9.  #ifdef NO_SCAN_BRACK /* Version_ Pts DgnLevs_ Hp___ Died__Born id */
  10.      static const char fmt[] = "%d %d %d %ld %d %d %d %d %d %d %ld %ld %d%*c";
  11.      static const char fmt32[] = "%c%c %s %s%*c";
  12.      static const char fmt33[] = "%s %s %s %s %s %s%*c";
  13.  #else
  14.      static const char fmt[] = "%d.%d.%d %ld %d %d %d %d %d %d %ld %ld %d ";
  15.      static const char fmt32[] = "%c%c %[^,],%[^\n]%*c";
  16.      static const char fmt33[] = "%s %s %s %s %[^,],%[^\n]%*c";
  17.  #endif
  18.  
  19.  #ifdef UPDATE_RECORD_IN_PLACE
  20.      /* note: input below must read the record's terminating newline */
  21.      final_fpos = tt->fpos = ftell(rfile);
  22.  #endif
  23.  #define TTFIELDS 13
  24.      if (fscanf(rfile, fmt, &tt->ver_major, &tt->ver_minor, &tt->patchlevel,
  25.                 &tt->points, &tt->deathdnum, &tt->deathlev, &tt->maxlvl,
  26.                 &tt->hp, &tt->maxhp, &tt->deaths, &tt->deathdate,
  27.                 &tt->birthdate, &tt->uid) != TTFIELDS) {
  28.  #undef TTFIELDS
  29.          tt->points = 0;
  30.          discardexcess(rfile);
  31.      } else {
  32.          /* load remainder of record into a local buffer;
  33.             this imposes an implicit length limit of SCANBUFSZ
  34.             on every string field extracted from the buffer */
  35.          if (!fgets(inbuf, sizeof inbuf, rfile)) {
  36.              /* sscanf will fail and tt->points will be set to 0 */
  37.              *inbuf = '\0';
  38.          } else if (!index(inbuf, '\n')) {
  39.              Strcpy(&inbuf[sizeof inbuf - 2], "\n");
  40.              discardexcess(rfile);
  41.          }
  42.          /* Check for backwards compatibility */
  43.          if (tt->ver_major < 3 || (tt->ver_major == 3 && tt->ver_minor < 3)) {
  44.              int i;
  45.  
  46.              if (sscanf(inbuf, fmt32, tt->plrole, tt->plgend, s1, s2) == 4) {
  47.                  tt->plrole[1] = tt->plgend[1] = '\0'; /* read via %c */
  48.                  copynchars(tt->name, s1, (int) (sizeof tt->name) - 1);
  49.                  copynchars(tt->death, s2, (int) (sizeof tt->death) - 1);
  50.              } else
  51.                  tt->points = 0;
  52.              tt->plrole[1] = '\0';
  53.              if ((i = str2role(tt->plrole)) >= 0)
  54.                  Strcpy(tt->plrole, roles[i].filecode);
  55.              Strcpy(tt->plrace, "?");
  56.              Strcpy(tt->plgend, (tt->plgend[0] == 'M') ? "Mal" : "Fem");
  57.              Strcpy(tt->plalign, "?");
  58.          } else if (sscanf(inbuf, fmt33, s1, s2, s3, s4, s5, s6) == 6) {
  59.              copynchars(tt->plrole, s1, (int) (sizeof tt->plrole) - 1);
  60.              copynchars(tt->plrace, s2, (int) (sizeof tt->plrace) - 1);
  61.              copynchars(tt->plgend, s3, (int) (sizeof tt->plgend) - 1);
  62.              copynchars(tt->plalign, s4, (int) (sizeof tt->plalign) - 1);
  63.              copynchars(tt->name, s5, (int) (sizeof tt->name) - 1);
  64.              copynchars(tt->death, s6, (int) (sizeof tt->death) - 1);
  65.          } else
  66.              tt->points = 0;
  67.  #ifdef NO_SCAN_BRACK
  68.          if (tt->points > 0) {
  69.              nsb_unmung_line(tt->name);
  70.              nsb_unmung_line(tt->death);
  71.          }
  72.  #endif
  73.      }
  74.  
  75.      /* check old score entries for Y2K problem and fix whenever found */
  76.      if (tt->points > 0) {
  77.          if (tt->birthdate < 19000000L)
  78.              tt->birthdate += 19000000L;
  79.          if (tt->deathdate < 19000000L)
  80.              tt->deathdate += 19000000L;
  81.      }
  82.  }
  83.  

writeentry

  1.  STATIC_OVL void
  2.  writeentry(rfile, tt)
  3.  FILE *rfile;
  4.  struct toptenentry *tt;
  5.  {
  6.      static const char fmt32[] = "%c%c ";        /* role,gender */
  7.      static const char fmt33[] = "%s %s %s %s "; /* role,race,gndr,algn */
  8.  #ifndef NO_SCAN_BRACK
  9.      static const char fmt0[] = "%d.%d.%d %ld %d %d %d %d %d %d %ld %ld %d ";
  10.      static const char fmtX[] = "%s,%s%s%s\n";
  11.  #else /* NO_SCAN_BRACK */
  12.      static const char fmt0[] = "%d %d %d %ld %d %d %d %d %d %d %ld %ld %d ";
  13.      static const char fmtX[] = "%s %s%s%s\n";
  14.  
  15.      nsb_mung_line(tt->name);
  16.      nsb_mung_line(tt->death);
  17.  #endif
  18.  
  19.      (void) fprintf(rfile, fmt0, tt->ver_major, tt->ver_minor, tt->patchlevel,
  20.                     tt->points, tt->deathdnum, tt->deathlev, tt->maxlvl,
  21.                     tt->hp, tt->maxhp, tt->deaths, tt->deathdate,
  22.                     tt->birthdate, tt->uid);
  23.      if (tt->ver_major < 3 || (tt->ver_major == 3 && tt->ver_minor < 3))
  24.          (void) fprintf(rfile, fmt32, tt->plrole[0], tt->plgend[0]);
  25.      else
  26.          (void) fprintf(rfile, fmt33, tt->plrole, tt->plrace, tt->plgend,
  27.                         tt->plalign);
  28.      (void) fprintf(rfile, fmtX, onlyspace(tt->name) ? "_" : tt->name,
  29.                     tt->death,
  30.                     (multi ? ", while " : ""),
  31.                     (multi ? (multi_reason ? multi_reason : "helpless") : ""));
  32.  
  33.  #ifdef NO_SCAN_BRACK
  34.      nsb_unmung_line(tt->name);
  35.      nsb_unmung_line(tt->death);
  36.  #endif
  37.  }
  38.  

writexlentry

  1.  /* as tab is never used in eg. plname or death, no need to mangle those. */
  2.  STATIC_OVL void
  3.  writexlentry(rfile, tt)
  4.  FILE *rfile;
  5.  struct toptenentry *tt;
  6.  {
  7.  #define Fprintf (void) fprintf
  8.  #define XLOG_SEP '\t' /* xlogfile field separator. */
  9.      char buf[BUFSZ];
  10.  
  11.      Sprintf(buf, "version=%d.%d.%d", tt->ver_major, tt->ver_minor,
  12.              tt->patchlevel);
  13.      Sprintf(eos(buf), "%cpoints=%ld%cdeathdnum=%d%cdeathlev=%d", XLOG_SEP,
  14.              tt->points, XLOG_SEP, tt->deathdnum, XLOG_SEP, tt->deathlev);
  15.      Sprintf(eos(buf), "%cmaxlvl=%d%chp=%d%cmaxhp=%d", XLOG_SEP, tt->maxlvl,
  16.              XLOG_SEP, tt->hp, XLOG_SEP, tt->maxhp);
  17.      Sprintf(eos(buf), "%cdeaths=%d%cdeathdate=%ld%cbirthdate=%ld%cuid=%d",
  18.              XLOG_SEP, tt->deaths, XLOG_SEP, tt->deathdate, XLOG_SEP,
  19.              tt->birthdate, XLOG_SEP, tt->uid);
  20.      Fprintf(rfile, "%s", buf);
  21.      Sprintf(buf, "%crole=%s%crace=%s%cgender=%s%calign=%s", XLOG_SEP,
  22.              tt->plrole, XLOG_SEP, tt->plrace, XLOG_SEP, tt->plgend, XLOG_SEP,
  23.              tt->plalign);
  24.      Fprintf(rfile, "%s%cname=%s%cdeath=%s",
  25.              buf, /* (already includes separator) */
  26.              XLOG_SEP, plname, XLOG_SEP, tt->death);
  27.      if (multi)
  28.          Fprintf(rfile, "%cwhile=%s", XLOG_SEP,
  29.                  multi_reason ? multi_reason : "helpless");
  30.      Fprintf(rfile, "%cconduct=0x%lx%cturns=%ld%cachieve=0x%lx", XLOG_SEP,
  31.              encodeconduct(), XLOG_SEP, moves, XLOG_SEP, encodeachieve());
  32.      Fprintf(rfile, "%crealtime=%ld%cstarttime=%ld%cendtime=%ld", XLOG_SEP,
  33.              (long) urealtime.realtime, XLOG_SEP, (long) ubirthday, XLOG_SEP,
  34.              (long) urealtime.endtime);
  35.      Fprintf(rfile, "%cgender0=%s%calign0=%s", XLOG_SEP,
  36.              genders[flags.initgend].filecode, XLOG_SEP,
  37.              aligns[1 - u.ualignbase[A_ORIGINAL]].filecode);
  38.      Fprintf(rfile, "%cflags=0x%lx", XLOG_SEP, encodexlogflags());
  39.      Fprintf(rfile, "\n");
  40.  #undef XLOG_SEP
  41.  }
  42.  

encodexlogflags

  1.  STATIC_OVL long
  2.  encodexlogflags()
  3.  {
  4.      long e = 0L;
  5.  
  6.      if (wizard)
  7.          e |= 1L << 0;
  8.      if (discover)
  9.          e |= 1L << 1;
  10.      if (!u.uroleplay.numbones)
  11.          e |= 1L << 2;
  12.  
  13.      return e;
  14.  }
  15.  

encodeconduct

  1.  STATIC_OVL long
  2.  encodeconduct()
  3.  {
  4.      long e = 0L;
  5.  
  6.      if (!u.uconduct.food)
  7.          e |= 1L << 0;
  8.      if (!u.uconduct.unvegan)
  9.          e |= 1L << 1;
  10.      if (!u.uconduct.unvegetarian)
  11.          e |= 1L << 2;
  12.      if (!u.uconduct.gnostic)
  13.          e |= 1L << 3;
  14.      if (!u.uconduct.weaphit)
  15.          e |= 1L << 4;
  16.      if (!u.uconduct.killer)
  17.          e |= 1L << 5;
  18.      if (!u.uconduct.literate)
  19.          e |= 1L << 6;
  20.      if (!u.uconduct.polypiles)
  21.          e |= 1L << 7;
  22.      if (!u.uconduct.polyselfs)
  23.          e |= 1L << 8;
  24.      if (!u.uconduct.wishes)
  25.          e |= 1L << 9;
  26.      if (!u.uconduct.wisharti)
  27.          e |= 1L << 10;
  28.      if (!num_genocides())
  29.          e |= 1L << 11;
  30.  
  31.      return e;
  32.  }
  33.  

encodeachieve

  1.  STATIC_OVL long
  2.  encodeachieve()
  3.  {
  4.      long r = 0L;
  5.  
  6.      if (u.uachieve.bell)
  7.          r |= 1L << 0;
  8.      if (u.uachieve.enter_gehennom)
  9.          r |= 1L << 1;
  10.      if (u.uachieve.menorah)
  11.          r |= 1L << 2;
  12.      if (u.uachieve.book)
  13.          r |= 1L << 3;
  14.      if (u.uevent.invoked)
  15.          r |= 1L << 4;
  16.      if (u.uachieve.amulet)
  17.          r |= 1L << 5;
  18.      if (In_endgame(&u.uz))
  19.          r |= 1L << 6;
  20.      if (Is_astralevel(&u.uz))
  21.          r |= 1L << 7;
  22.      if (u.uachieve.ascended)
  23.          r |= 1L << 8;
  24.      if (u.uachieve.mines_luckstone)
  25.          r |= 1L << 9;
  26.      if (u.uachieve.finish_sokoban)
  27.          r |= 1L << 10;
  28.      if (u.uachieve.killed_medusa)
  29.          r |= 1L << 11;
  30.      if (u.uroleplay.blind)
  31.          r |= 1L << 12;
  32.      if (u.uroleplay.nudist)
  33.          r |= 1L << 13;
  34.  
  35.      return r;
  36.  }
  37.  

free_ttlist

  1.  STATIC_OVL void
  2.  free_ttlist(tt)
  3.  struct toptenentry *tt;
  4.  {
  5.      struct toptenentry *ttnext;
  6.  
  7.      while (tt->points > 0) {
  8.          ttnext = tt->tt_next;
  9.          dealloc_ttentry(tt);
  10.          tt = ttnext;
  11.      }
  12.      dealloc_ttentry(tt);
  13.  }
  14.  

topten

  1.  void
  2.  topten(how, when)
  3.  int how;
  4.  time_t when;
  5.  {
  6.      int uid = getuid();
  7.      int rank, rank0 = -1, rank1 = 0;
  8.      int occ_cnt = sysopt.persmax;
  9.      register struct toptenentry *t0, *tprev;
  10.      struct toptenentry *t1;
  11.      FILE *rfile;
  12.      register int flg = 0;
  13.      boolean t0_used;
  14.  #ifdef LOGFILE
  15.      FILE *lfile;
  16.  #endif /* LOGFILE */
  17.  #ifdef XLOGFILE
  18.      FILE *xlfile;
  19.  #endif /* XLOGFILE */
  20.  
  21.  #ifdef _DCC
  22.      /* Under DICE 3.0, this crashes the system consistently, apparently due to
  23.       * corruption of *rfile somewhere.  Until I figure this out, just cut out
  24.       * topten support entirely - at least then the game exits cleanly.  --AC
  25.       */
  26.      return;
  27.  #endif
  28.  
  29.      /* If we are in the midst of a panic, cut out topten entirely.
  30.       * topten uses alloc() several times, which will lead to
  31.       * problems if the panic was the result of an alloc() failure.
  32.       */
  33.      if (program_state.panicking)
  34.          return;
  35.  
  36.      if (iflags.toptenwin) {
  37.          toptenwin = create_nhwindow(NHW_TEXT);
  38.      }
  39.  
  40.  #if defined(UNIX) || defined(VMS) || defined(__EMX__)
  41.  #define HUP if (!program_state.done_hup)
  42.  #else
  43.  #define HUP
  44.  #endif
  45.  
  46.  #ifdef TOS
  47.      restore_colors(); /* make sure the screen is black on white */
  48.  #endif
  49.      /* create a new 'topten' entry */
  50.      t0_used = FALSE;
  51.      t0 = newttentry();
  52.      t0->ver_major = VERSION_MAJOR;
  53.      t0->ver_minor = VERSION_MINOR;
  54.      t0->patchlevel = PATCHLEVEL;
  55.      t0->points = u.urexp;
  56.      t0->deathdnum = u.uz.dnum;
  57.      /* deepest_lev_reached() is in terms of depth(), and reporting the
  58.       * deepest level reached in the dungeon death occurred in doesn't
  59.       * seem right, so we have to report the death level in depth() terms
  60.       * as well (which also seems reasonable since that's all the player
  61.       * sees on the screen anyway)
  62.       */
  63.      t0->deathlev = observable_depth(&u.uz);
  64.      t0->maxlvl = deepest_lev_reached(TRUE);
  65.      t0->hp = u.uhp;
  66.      t0->maxhp = u.uhpmax;
  67.      t0->deaths = u.umortality;
  68.      t0->uid = uid;
  69.      copynchars(t0->plrole, urole.filecode, ROLESZ);
  70.      copynchars(t0->plrace, urace.filecode, ROLESZ);
  71.      copynchars(t0->plgend, genders[flags.female].filecode, ROLESZ);
  72.      copynchars(t0->plalign, aligns[1 - u.ualign.type].filecode, ROLESZ);
  73.      copynchars(t0->name, plname, NAMSZ);
  74.      formatkiller(t0->death, sizeof t0->death, how);
  75.      t0->birthdate = yyyymmdd(ubirthday);
  76.      t0->deathdate = yyyymmdd(when);
  77.      t0->tt_next = 0;
  78.      urealtime.endtime = when;
  79.  #ifdef UPDATE_RECORD_IN_PLACE
  80.      t0->fpos = -1L;
  81.  #endif
  82.  
  83.  #ifdef LOGFILE /* used for debugging (who dies of what, where) */
  84.      if (lock_file(LOGFILE, SCOREPREFIX, 10)) {
  85.          if (!(lfile = fopen_datafile(LOGFILE, "a", SCOREPREFIX))) {
  86.              HUP raw_print("Cannot open log file!");
  87.          } else {
  88.              writeentry(lfile, t0);
  89.              (void) fclose(lfile);
  90.          }
  91.          unlock_file(LOGFILE);
  92.      }
  93.  #endif /* LOGFILE */
  94.  #ifdef XLOGFILE
  95.      if (lock_file(XLOGFILE, SCOREPREFIX, 10)) {
  96.          if (!(xlfile = fopen_datafile(XLOGFILE, "a", SCOREPREFIX))) {
  97.              HUP raw_print("Cannot open extended log file!");
  98.          } else {
  99.              writexlentry(xlfile, t0);
  100.              (void) fclose(xlfile);
  101.          }
  102.          unlock_file(XLOGFILE);
  103.      }
  104.  #endif /* XLOGFILE */
  105.  
  106.      if (wizard || discover) {
  107.          if (how != PANICKED)
  108.              HUP {
  109.                  char pbuf[BUFSZ];
  110.                  topten_print("");
  111.                  Sprintf(pbuf,
  112.               "Since you were in %s mode, the score list will not be checked.",
  113.                          wizard ? "wizard" : "discover");
  114.                  topten_print(pbuf);
  115.              }
  116.          goto showwin;
  117.      }
  118.  
  119.      if (!lock_file(RECORD, SCOREPREFIX, 60))
  120.          goto destroywin;
  121.  
  122.  #ifdef UPDATE_RECORD_IN_PLACE
  123.      rfile = fopen_datafile(RECORD, "r+", SCOREPREFIX);
  124.  #else
  125.      rfile = fopen_datafile(RECORD, "r", SCOREPREFIX);
  126.  #endif
  127.  
  128.      if (!rfile) {
  129.          HUP raw_print("Cannot open record file!");
  130.          unlock_file(RECORD);
  131.          goto destroywin;
  132.      }
  133.  
  134.      HUP topten_print("");
  135.  
  136.      /* assure minimum number of points */
  137.      if (t0->points < sysopt.pointsmin)
  138.          t0->points = 0;
  139.  
  140.      t1 = tt_head = newttentry();
  141.      tprev = 0;
  142.      /* rank0: -1 undefined, 0 not_on_list, n n_th on list */
  143.      for (rank = 1;;) {
  144.          readentry(rfile, t1);
  145.          if (t1->points < sysopt.pointsmin)
  146.              t1->points = 0;
  147.          if (rank0 < 0 && t1->points < t0->points) {
  148.              rank0 = rank++;
  149.              if (tprev == 0)
  150.                  tt_head = t0;
  151.              else
  152.                  tprev->tt_next = t0;
  153.              t0->tt_next = t1;
  154.  #ifdef UPDATE_RECORD_IN_PLACE
  155.              t0->fpos = t1->fpos; /* insert here */
  156.  #endif
  157.              t0_used = TRUE;
  158.              occ_cnt--;
  159.              flg++; /* ask for a rewrite */
  160.          } else
  161.              tprev = t1;
  162.  
  163.          if (t1->points == 0)
  164.              break;
  165.          if ((sysopt.pers_is_uid ? t1->uid == t0->uid
  166.                                  : strncmp(t1->name, t0->name, NAMSZ) == 0)
  167.              && !strncmp(t1->plrole, t0->plrole, ROLESZ) && --occ_cnt <= 0) {
  168.              if (rank0 < 0) {
  169.                  rank0 = 0;
  170.                  rank1 = rank;
  171.                  HUP {
  172.                      char pbuf[BUFSZ];
  173.  
  174.                      Sprintf(pbuf,
  175.                          "You didn't beat your previous score of %ld points.",
  176.                              t1->points);
  177.                      topten_print(pbuf);
  178.                      topten_print("");
  179.                  }
  180.              }
  181.              if (occ_cnt < 0) {
  182.                  flg++;
  183.                  continue;
  184.              }
  185.          }
  186.          if (rank <= sysopt.entrymax) {
  187.              t1->tt_next = newttentry();
  188.              t1 = t1->tt_next;
  189.              rank++;
  190.          }
  191.          if (rank > sysopt.entrymax) {
  192.              t1->points = 0;
  193.              break;
  194.          }
  195.      }
  196.      if (flg) { /* rewrite record file */
  197.  #ifdef UPDATE_RECORD_IN_PLACE
  198.          (void) fseek(rfile, (t0->fpos >= 0 ? t0->fpos : final_fpos),
  199.                       SEEK_SET);
  200.  #else
  201.          (void) fclose(rfile);
  202.          if (!(rfile = fopen_datafile(RECORD, "w", SCOREPREFIX))) {
  203.              HUP raw_print("Cannot write record file");
  204.              unlock_file(RECORD);
  205.              free_ttlist(tt_head);
  206.              goto destroywin;
  207.          }
  208.  #endif /* UPDATE_RECORD_IN_PLACE */
  209.          if (!done_stopprint)
  210.              if (rank0 > 0) {
  211.                  if (rank0 <= 10) {
  212.                      topten_print("You made the top ten list!");
  213.                  } else {
  214.                      char pbuf[BUFSZ];
  215.  
  216.                      Sprintf(pbuf,
  217.                              "You reached the %d%s place on the top %d list.",
  218.                              rank0, ordin(rank0), sysopt.entrymax);
  219.                      topten_print(pbuf);
  220.                  }
  221.                  topten_print("");
  222.              }
  223.      }
  224.      if (rank0 == 0)
  225.          rank0 = rank1;
  226.      if (rank0 <= 0)
  227.          rank0 = rank;
  228.      if (!done_stopprint)
  229.          outheader();
  230.      t1 = tt_head;
  231.      for (rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
  232.          if (flg
  233.  #ifdef UPDATE_RECORD_IN_PLACE
  234.              && rank >= rank0
  235.  #endif
  236.              )
  237.              writeentry(rfile, t1);
  238.          if (done_stopprint)
  239.              continue;
  240.          if (rank > flags.end_top && (rank < rank0 - flags.end_around
  241.                                       || rank > rank0 + flags.end_around)
  242.              && (!flags.end_own
  243.                  || (sysopt.pers_is_uid
  244.                          ? t1->uid == t0->uid
  245.                          : strncmp(t1->name, t0->name, NAMSZ) == 0)))
  246.              continue;
  247.          if (rank == rank0 - flags.end_around
  248.              && rank0 > flags.end_top + flags.end_around + 1 && !flags.end_own)
  249.              topten_print("");
  250.          if (rank != rank0)
  251.              outentry(rank, t1, FALSE);
  252.          else if (!rank1)
  253.              outentry(rank, t1, TRUE);
  254.          else {
  255.              outentry(rank, t1, TRUE);
  256.              outentry(0, t0, TRUE);
  257.          }
  258.      }
  259.      if (rank0 >= rank)
  260.          if (!done_stopprint)
  261.              outentry(0, t0, TRUE);
  262.  #ifdef UPDATE_RECORD_IN_PLACE
  263.      if (flg) {
  264.  #ifdef TRUNCATE_FILE
  265.          /* if a reasonable way to truncate a file exists, use it */
  266.          truncate_file(rfile);
  267.  #else
  268.          /* use sentinel record rather than relying on truncation */
  269.          t1->points = 0L; /* terminates file when read back in */
  270.          t1->ver_major = t1->ver_minor = t1->patchlevel = 0;
  271.          t1->uid = t1->deathdnum = t1->deathlev = 0;
  272.          t1->maxlvl = t1->hp = t1->maxhp = t1->deaths = 0;
  273.          t1->plrole[0] = t1->plrace[0] = t1->plgend[0] = t1->plalign[0] = '-';
  274.          t1->plrole[1] = t1->plrace[1] = t1->plgend[1] = t1->plalign[1] = 0;
  275.          t1->birthdate = t1->deathdate = yyyymmdd((time_t) 0L);
  276.          Strcpy(t1->name, "@");
  277.          Strcpy(t1->death, "<eod>\n");
  278.          writeentry(rfile, t1);
  279.          (void) fflush(rfile);
  280.  #endif /* TRUNCATE_FILE */
  281.      }
  282.  #endif /* UPDATE_RECORD_IN_PLACE */
  283.      (void) fclose(rfile);
  284.      unlock_file(RECORD);
  285.      free_ttlist(tt_head);
  286.  
  287.  showwin:
  288.      if (iflags.toptenwin && !done_stopprint)
  289.          display_nhwindow(toptenwin, 1);
  290.  destroywin:
  291.      if (!t0_used)
  292.          dealloc_ttentry(t0);
  293.      if (iflags.toptenwin) {
  294.          destroy_nhwindow(toptenwin);
  295.          toptenwin = WIN_ERR;
  296.      }
  297.  }
  298.  

outheader

  1.  STATIC_OVL void
  2.  outheader()
  3.  {
  4.      char linebuf[BUFSZ];
  5.      register char *bp;
  6.  
  7.      Strcpy(linebuf, " No  Points     Name");
  8.      bp = eos(linebuf);
  9.      while (bp < linebuf + COLNO - 9)
  10.          *bp++ = ' ';
  11.      Strcpy(bp, "Hp [max]");
  12.      topten_print(linebuf);
  13.  }
  14.  

outentry

  1.  /* so>0: standout line; so=0: ordinary line */
  2.  STATIC_OVL void
  3.  outentry(rank, t1, so)
  4.  struct toptenentry *t1;
  5.  int rank;
  6.  boolean so;
  7.  {
  8.      boolean second_line = TRUE;
  9.      char linebuf[BUFSZ];
  10.      char *bp, hpbuf[24], linebuf3[BUFSZ];
  11.      int hppos, lngr;
  12.  
  13.      linebuf[0] = '\0';
  14.      if (rank)
  15.          Sprintf(eos(linebuf), "%3d", rank);
  16.      else
  17.          Strcat(linebuf, "   ");
  18.  
  19.      Sprintf(eos(linebuf), " %10ld  %.10s", t1->points ? t1->points : u.urexp,
  20.              t1->name);
  21.      Sprintf(eos(linebuf), "-%s", t1->plrole);
  22.      if (t1->plrace[0] != '?')
  23.          Sprintf(eos(linebuf), "-%s", t1->plrace);
  24.      /* Printing of gender and alignment is intentional.  It has been
  25.       * part of the NetHack Geek Code, and illustrates a proper way to
  26.       * specify a character from the command line.
  27.       */
  28.      Sprintf(eos(linebuf), "-%s", t1->plgend);
  29.      if (t1->plalign[0] != '?')
  30.          Sprintf(eos(linebuf), "-%s ", t1->plalign);
  31.      else
  32.          Strcat(linebuf, " ");
  33.      if (!strncmp("escaped", t1->death, 7)) {
  34.          Sprintf(eos(linebuf), "escaped the dungeon %s[max level %d]",
  35.                  !strncmp(" (", t1->death + 7, 2) ? t1->death + 7 + 2 : "",
  36.                  t1->maxlvl);
  37.          /* fixup for closing paren in "escaped... with...Amulet)[max..." */
  38.          if ((bp = index(linebuf, ')')) != 0)
  39.              *bp = (t1->deathdnum == astral_level.dnum) ? '\0' : ' ';
  40.          second_line = FALSE;
  41.      } else if (!strncmp("ascended", t1->death, 8)) {
  42.          Sprintf(eos(linebuf), "ascended to demigod%s-hood",
  43.                  (t1->plgend[0] == 'F') ? "dess" : "");
  44.          second_line = FALSE;
  45.      } else {
  46.          if (!strncmp(t1->death, "quit", 4)) {
  47.              Strcat(linebuf, "quit");
  48.              second_line = FALSE;
  49.          } else if (!strncmp(t1->death, "died of st", 10)) {
  50.              Strcat(linebuf, "starved to death");
  51.              second_line = FALSE;
  52.          } else if (!strncmp(t1->death, "choked", 6)) {
  53.              Sprintf(eos(linebuf), "choked on h%s food",
  54.                      (t1->plgend[0] == 'F') ? "er" : "is");
  55.          } else if (!strncmp(t1->death, "poisoned", 8)) {
  56.              Strcat(linebuf, "was poisoned");
  57.          } else if (!strncmp(t1->death, "crushed", 7)) {
  58.              Strcat(linebuf, "was crushed to death");
  59.          } else if (!strncmp(t1->death, "petrified by ", 13)) {
  60.              Strcat(linebuf, "turned to stone");
  61.          } else
  62.              Strcat(linebuf, "died");
  63.  
  64.          if (t1->deathdnum == astral_level.dnum) {
  65.              const char *arg, *fmt = " on the Plane of %s";
  66.  
  67.              switch (t1->deathlev) {
  68.              case -5:
  69.                  fmt = " on the %s Plane";
  70.                  arg = "Astral";
  71.                  break;
  72.              case -4:
  73.                  arg = "Water";
  74.                  break;
  75.              case -3:
  76.                  arg = "Fire";
  77.                  break;
  78.              case -2:
  79.                  arg = "Air";
  80.                  break;
  81.              case -1:
  82.                  arg = "Earth";
  83.                  break;
  84.              default:
  85.                  arg = "Void";
  86.                  break;
  87.              }
  88.              Sprintf(eos(linebuf), fmt, arg);
  89.          } else {
  90.              Sprintf(eos(linebuf), " in %s", dungeons[t1->deathdnum].dname);
  91.              if (t1->deathdnum != knox_level.dnum)
  92.                  Sprintf(eos(linebuf), " on level %d", t1->deathlev);
  93.              if (t1->deathlev != t1->maxlvl)
  94.                  Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
  95.          }
  96.  
  97.          /* kludge for "quit while already on Charon's boat" */
  98.          if (!strncmp(t1->death, "quit ", 5))
  99.              Strcat(linebuf, t1->death + 4);
  100.      }
  101.      Strcat(linebuf, ".");
  102.  
  103.      /* Quit, starved, ascended, and escaped contain no second line */
  104.      if (second_line)
  105.          Sprintf(eos(linebuf), "  %c%s.", highc(*(t1->death)), t1->death + 1);
  106.  
  107.      lngr = (int) strlen(linebuf);
  108.      if (t1->hp <= 0)
  109.          hpbuf[0] = '-', hpbuf[1] = '\0';
  110.      else
  111.          Sprintf(hpbuf, "%d", t1->hp);
  112.      /* beginning of hp column after padding (not actually padded yet) */
  113.      hppos = COLNO - (sizeof("  Hp [max]") - 1); /* sizeof(str) includes \0 */
  114.      while (lngr >= hppos) {
  115.          for (bp = eos(linebuf); !(*bp == ' ' && (bp - linebuf < hppos)); bp--)
  116.              ;
  117.          /* special case: word is too long, wrap in the middle */
  118.          if (linebuf + 15 >= bp)
  119.              bp = linebuf + hppos - 1;
  120.          /* special case: if about to wrap in the middle of maximum
  121.             dungeon depth reached, wrap in front of it instead */
  122.          if (bp > linebuf + 5 && !strncmp(bp - 5, " [max", 5))
  123.              bp -= 5;
  124.          if (*bp != ' ')
  125.              Strcpy(linebuf3, bp);
  126.          else
  127.              Strcpy(linebuf3, bp + 1);
  128.          *bp = 0;
  129.          if (so) {
  130.              while (bp < linebuf + (COLNO - 1))
  131.                  *bp++ = ' ';
  132.              *bp = 0;
  133.              topten_print_bold(linebuf);
  134.          } else
  135.              topten_print(linebuf);
  136.          Sprintf(linebuf, "%15s %s", "", linebuf3);
  137.          lngr = strlen(linebuf);
  138.      }
  139.      /* beginning of hp column not including padding */
  140.      hppos = COLNO - 7 - (int) strlen(hpbuf);
  141.      bp = eos(linebuf);
  142.  
  143.      if (bp <= linebuf + hppos) {
  144.          /* pad any necessary blanks to the hit point entry */
  145.          while (bp < linebuf + hppos)
  146.              *bp++ = ' ';
  147.          Strcpy(bp, hpbuf);
  148.          Sprintf(eos(bp), " %s[%d]",
  149.                  (t1->maxhp < 10) ? "  " : (t1->maxhp < 100) ? " " : "",
  150.                  t1->maxhp);
  151.      }
  152.  
  153.      if (so) {
  154.          bp = eos(linebuf);
  155.          if (so >= COLNO)
  156.              so = COLNO - 1;
  157.          while (bp < linebuf + so)
  158.              *bp++ = ' ';
  159.          *bp = 0;
  160.          topten_print_bold(linebuf);
  161.      } else
  162.          topten_print(linebuf);
  163.  }
  164.  

score_wanted

  1.  STATIC_OVL int
  2.  score_wanted(current_ver, rank, t1, playerct, players, uid)
  3.  boolean current_ver;
  4.  int rank;
  5.  struct toptenentry *t1;
  6.  int playerct;
  7.  const char **players;
  8.  int uid;
  9.  {
  10.      int i;
  11.  
  12.      if (current_ver
  13.          && (t1->ver_major != VERSION_MAJOR || t1->ver_minor != VERSION_MINOR
  14.              || t1->patchlevel != PATCHLEVEL))
  15.          return 0;
  16.  
  17.      if (sysopt.pers_is_uid && !playerct && t1->uid == uid)
  18.          return 1;
  19.  
  20.      for (i = 0; i < playerct; i++) {
  21.          if (players[i][0] == '-' && index("pr", players[i][1])
  22.              && players[i][2] == 0 && i + 1 < playerct) {
  23.              const char *arg = players[i + 1];
  24.              if ((players[i][1] == 'p'
  25.                   && str2role(arg) == str2role(t1->plrole))
  26.                  || (players[i][1] == 'r'
  27.                      && str2race(arg) == str2race(t1->plrace)))
  28.                  return 1;
  29.              i++;
  30.          } else if (strcmp(players[i], "all") == 0
  31.                     || strncmp(t1->name, players[i], NAMSZ) == 0
  32.                     || (players[i][0] == '-' && players[i][1] == t1->plrole[0]
  33.                         && players[i][2] == 0)
  34.                     || (digit(players[i][0]) && rank <= atoi(players[i])))
  35.              return 1;
  36.      }
  37.      return 0;
  38.  }
  39.  

prscore

  1.  /*
  2.   * print selected parts of score list.
  3.   * argc >= 2, with argv[0] untrustworthy (directory names, et al.),
  4.   * and argv[1] starting with "-s".
  5.   */
  6.  void
  7.  prscore(argc, argv)
  8.  int argc;
  9.  char **argv;
  10.  {
  11.      const char **players;
  12.      int playerct, rank;
  13.      boolean current_ver = TRUE, init_done = FALSE;
  14.      register struct toptenentry *t1;
  15.      FILE *rfile;
  16.      boolean match_found = FALSE;
  17.      register int i;
  18.      char pbuf[BUFSZ];
  19.      int uid = -1;
  20.      const char *player0;
  21.  
  22.      if (argc < 2 || strncmp(argv[1], "-s", 2)) {
  23.          raw_printf("prscore: bad arguments (%d)", argc);
  24.          return;
  25.      }
  26.  
  27.      rfile = fopen_datafile(RECORD, "r", SCOREPREFIX);
  28.      if (!rfile) {
  29.          raw_print("Cannot open record file!");
  30.          return;
  31.      }
  32.  
  33.  #ifdef AMIGA
  34.      {
  35.          extern winid amii_rawprwin;
  36.  
  37.          init_nhwindows(&argc, argv);
  38.          amii_rawprwin = create_nhwindow(NHW_TEXT);
  39.      }
  40.  #endif
  41.  
  42.      /* If the score list isn't after a game, we never went through
  43.       * initialization. */
  44.      if (wiz1_level.dlevel == 0) {
  45.          dlb_init();
  46.          init_dungeons();
  47.          init_done = TRUE;
  48.      }
  49.  
  50.      if (!argv[1][2]) { /* plain "-s" */
  51.          argc--;
  52.          argv++;
  53.      } else
  54.          argv[1] += 2;
  55.  
  56.      if (argc > 1 && !strcmp(argv[1], "-v")) {
  57.          current_ver = FALSE;
  58.          argc--;
  59.          argv++;
  60.      }
  61.  
  62.      if (argc <= 1) {
  63.          if (sysopt.pers_is_uid) {
  64.              uid = getuid();
  65.              playerct = 0;
  66.              players = (const char **) 0;
  67.          } else {
  68.              player0 = plname;
  69.              if (!*player0)
  70.  #ifdef AMIGA
  71.                  player0 = "all"; /* single user system */
  72.  #else
  73.                  player0 = "hackplayer";
  74.  #endif
  75.              playerct = 1;
  76.              players = &player0;
  77.          }
  78.      } else {
  79.          playerct = --argc;
  80.          players = (const char **) ++argv;
  81.      }
  82.      raw_print("");
  83.  
  84.      t1 = tt_head = newttentry();
  85.      for (rank = 1;; rank++) {
  86.          readentry(rfile, t1);
  87.          if (t1->points == 0)
  88.              break;
  89.          if (!match_found
  90.              && score_wanted(current_ver, rank, t1, playerct, players, uid))
  91.              match_found = TRUE;
  92.          t1->tt_next = newttentry();
  93.          t1 = t1->tt_next;
  94.      }
  95.  
  96.      (void) fclose(rfile);
  97.      if (init_done) {
  98.          free_dungeons();
  99.          dlb_cleanup();
  100.      }
  101.  
  102.      if (match_found) {
  103.          outheader();
  104.          t1 = tt_head;
  105.          for (rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
  106.              if (score_wanted(current_ver, rank, t1, playerct, players, uid))
  107.                  (void) outentry(rank, t1, FALSE);
  108.          }
  109.      } else {
  110.          Sprintf(pbuf, "Cannot find any %sentries for ",
  111.                  current_ver ? "current " : "");
  112.          if (playerct < 1)
  113.              Strcat(pbuf, "you.");
  114.          else {
  115.              if (playerct > 1)
  116.                  Strcat(pbuf, "any of ");
  117.              for (i = 0; i < playerct; i++) {
  118.                  /* stop printing players if there are too many to fit */
  119.                  if (strlen(pbuf) + strlen(players[i]) + 2 >= BUFSZ) {
  120.                      if (strlen(pbuf) < BUFSZ - 4)
  121.                          Strcat(pbuf, "...");
  122.                      else
  123.                          Strcpy(pbuf + strlen(pbuf) - 4, "...");
  124.                      break;
  125.                  }
  126.                  Strcat(pbuf, players[i]);
  127.                  if (i < playerct - 1) {
  128.                      if (players[i][0] == '-' && index("pr", players[i][1])
  129.                          && players[i][2] == 0)
  130.                          Strcat(pbuf, " ");
  131.                      else
  132.                          Strcat(pbuf, ":");
  133.                  }
  134.              }
  135.          }
  136.          raw_print(pbuf);
  137.          raw_printf("Usage: %s -s [-v] <playertypes> [maxrank] [playernames]",
  138.  
  139.                     hname);
  140.          raw_printf("Player types are: [-p role] [-r race]");
  141.      }
  142.      free_ttlist(tt_head);
  143.  #ifdef AMIGA
  144.      {
  145.          extern winid amii_rawprwin;
  146.  
  147.          display_nhwindow(amii_rawprwin, 1);
  148.          destroy_nhwindow(amii_rawprwin);
  149.          amii_rawprwin = WIN_ERR;
  150.      }
  151.  #endif
  152.  }
  153.  

classmon

  1.  STATIC_OVL int
  2.  classmon(plch, fem)
  3.  char *plch;
  4.  boolean fem;
  5.  {
  6.      int i;
  7.  
  8.      /* Look for this role in the role table */
  9.      for (i = 0; roles[i].name.m; i++)
  10.          if (!strncmp(plch, roles[i].filecode, ROLESZ)) {
  11.              if (fem && roles[i].femalenum != NON_PM)
  12.                  return roles[i].femalenum;
  13.              else if (roles[i].malenum != NON_PM)
  14.                  return roles[i].malenum;
  15.              else
  16.                  return PM_HUMAN;
  17.          }
  18.      /* this might be from a 3.2.x score for former Elf class */
  19.      if (!strcmp(plch, "E"))
  20.          return PM_RANGER;
  21.  
  22.      impossible("What weird role is this? (%s)", plch);
  23.      return  PM_HUMAN_MUMMY;
  24.  }
  25.  

tt_oname

  1.  /*
  2.   * Get a random player name and class from the high score list,
  3.   * and attach them to an object (for statues or morgue corpses).
  4.   */
  5.  struct obj *
  6.  tt_oname(otmp)
  7.  struct obj *otmp;
  8.  {
  9.      int rank;
  10.      register int i;
  11.      register struct toptenentry *tt;
  12.      FILE *rfile;
  13.      struct toptenentry tt_buf;
  14.  
  15.      if (!otmp)
  16.          return (struct obj *) 0;
  17.  
  18.      rfile = fopen_datafile(RECORD, "r", SCOREPREFIX);
  19.      if (!rfile) {
  20.          impossible("Cannot open record file!");
  21.          return (struct obj *) 0;
  22.      }
  23.  
  24.      tt = &tt_buf;
  25.      rank = rnd(sysopt.tt_oname_maxrank);
  26.  pickentry:
  27.      for (i = rank; i; i--) {
  28.          readentry(rfile, tt);
  29.          if (tt->points == 0)
  30.              break;
  31.      }
  32.  
  33.      if (tt->points == 0) {
  34.          if (rank > 1) {
  35.              rank = 1;
  36.              rewind(rfile);
  37.              goto pickentry;
  38.          }
  39.          otmp = (struct obj *) 0;
  40.      } else {
  41.          set_corpsenm(otmp, classmon(tt->plrole, (tt->plgend[0] == 'F')));
  42.          otmp = oname(otmp, tt->name);
  43.      }
  44.  
  45.      (void) fclose(rfile);
  46.      return otmp;
  47.  }
  48.  

msbmunt_line

  1.  #ifdef NO_SCAN_BRACK
  2.  /* Lattice scanf isn't up to reading the scorefile.  What */
  3.  /* follows deals with that; I admit it's ugly. (KL) */
  4.  /* Now generally available (KL) */
  5.  STATIC_OVL void
  6.  nsb_mung_line(p)
  7.  char *p;
  8.  {
  9.      while ((p = index(p, ' ')) != 0)
  10.          *p = '|';
  11.  }
  12.  

nsb_unmung_line

  1.  STATIC_OVL void
  2.  nsb_unmung_line(p)
  3.  char *p;
  4.  {
  5.      while ((p = index(p, '|')) != 0)
  6.          *p = ' ';
  7.  }
  8.  #endif /* NO_SCAN_BRACK */
  9.  
  10.  /*topten.c*/