/* List the Nethack record file and the average score
   reclist -ffilename -l -uplayername -character -nnumber -d
*/

/* Original program for MS-DOS by J. Lahtinen, August 1993,
   usenet: walker@mits.mdata.fi
   Adapted for Unix, -l option added, sources translated from finnish,
   by Boudewijn Wayers, March 1994, usenet: dedos4@win.tue.nl
*/

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define RECORD	"/home/svin04d/dedos4/bin/nethackdir/record"
#define LOGFILE	"/home/svin04d/dedos4/bin/nethackdir/logfile"
#define VERSION	"2.2"

char *ver[]="2.2";  /* version */

int main(argc, argv)
int argc;
char *argv[];
{
 FILE *input;

 int  i,
      num=0,
      maxscores=0,
      d=0;
 long sum=0;

 char class=0,
      line[150];

 char *name=NULL,
      *filename=RECORD;

 long checkline();
  int error();

 /* Command line parameters */
 for (i=1; i<argc; i++) {
    if (argv[i][0]=='/')
       argv[i][0]='-';
    if (argv[i][0]!='-')
       error(argv[0],argv[i]);
    if (!(strncmp(argv[i],"-f",2)))       /* filename        */
       if (strlen(argv[i])==2) {
          i++;
          filename=argv[i]; }
       else
          filename=argv[i]+2;
    else if (!(strncmp(argv[i],"-l",2)))  /* logfile request */
       filename=LOGFILE;
    else if (!(strncmp(argv[i],"-u",2)))  /* playername      */
       if (strlen(argv[i])==2) {
          i++;
          name=argv[i]; }
       else
          name=argv[i]+2;
    else if (!(strncmp(argv[i],"-n",2)))  /* number    */
       if (strlen(argv[i])==2) {
          i++;
          maxscores=atoi(argv[i]); }
       else
          maxscores=atoi(argv[i]+2);
    else if (argv[i][1]=='d')
       d=1;
    else
       if (argv[i][0]=='-') {
          switch (toupper(argv[i][1])) { /* character class */
             case 'A': case 'B': case 'C': case 'E': case 'H':
             case 'K': case 'P': case 'R': case 'S': case 'T':
             case 'V': case 'W':
                  class=toupper(argv[i][1]);
                  break;
             default:
                  error(argv[0],argv[i]);
 }     }  }

 /* Command line ok */

 if (!(input=fopen(filename,"r"))) {
    printf ("File %s not found\n",filename);
    exit (2);
 }
 printf("%-71s%s"," No     Points  Name","Hp [max]\n");
 fgets(line,150,input);
 while ((!(feof(input))) && ((!maxscores) || (num<maxscores))) {
   sum += checkline(line,name,class,&num,d);
   fgets(line,150,input);
 }
 if (num)
    printf("\n%d scores. Average score %ld.\n",num,sum/num);
 else
    printf("\nNo games found.\n");
 fclose (input);
 return 0;
}


/* Interpret one line of the file */

long checkline(line,playername,playerclass,num,d)
char *line;
char *playername;
char playerclass;
int *num;
int d;
{
 int  pos,
      pos2,
      dtype,
      dlev,
      maxlev,
      hp,
      maxhp;
 static int nro=0;
 long score,
      pvm;
 char class,
      gender,
      raato[70],
      ascend=0;
 char *syy;
 static char *dungeon[]={"The Dungeons of Doom",/* 0 */
                         "Gehennom",            /* 1 */
                         "The Gnomish Mines",   /* 2 */
                         "The Quest",           /* 3 */
                         "Fort Ludios",         /* 4 */
                         "Vlad's Tower",        /* 5 */
                         "The Endgame"};        /* 6 */

 nro++;

 sscanf (line,"%ld %*d %d %d %d %d %d %ld %c%c",
        &pvm,&dtype,&dlev,&maxlev,&hp,&maxhp,&score,&class,&gender);

 if (class<'A')
    return (0);
 if ((playerclass) && (playerclass!=class))
    return (0);

 for (pos=0;!isalpha(line[pos]);pos++);
 if (pos>strlen(line))  /* will not be in a valid file, just check.. */
    return (0);
 pos += 3;
 for (pos2=0;(line[pos]!=',')&&(pos2<sizeof(raato));pos2++,pos++)
    raato[pos2]=line[pos];
 raato[pos2]=0;

 if ((playername) && (strcmp(playername,raato)))
    return (0);

 printf("%3d%11ld  ",nro,score);
 syy= &line[pos+1];
 strcat(raato,"-");
 pos=strlen(raato);
 raato[pos]=class; raato[pos+1]=0;
 if (!(strncmp(syy,"poisoned",8)))
    strcat(raato," was poisoned");
 else if (!(strncmp(syy,"petrified",9)))
    strcat(raato," turned to stone");
 else if (!(strncmp(syy,"starvation",10)))
    strcat(raato," starved to death");
 else if (!(strncmp(syy,"choked",6)))
    if (gender=='M')
       strcat(raato," choked on his food");
    else
       strcat(raato," choked on her food");
 else if (!(strncmp(syy,"quit",4)))
          strcat(raato," quit");
 else if (!(strncmp(syy,"ascended",8))) {
    strcat(raato," ascended to demigod-hood");
    ascend=1; }
 else
    strcat(raato," died");
 if (!ascend) {
    pos=strlen(raato);
    sprintf (raato+pos," in %s on level %d",dungeon[dtype],dlev);
    if (maxlev!=dlev)
       sprintf(raato+strlen(raato)," [max %d].",maxlev);
    else strcat(raato,".");
    if (strlen(raato)>55) {
       raato[pos]=0;
       if (d) {
          printf ("%s\n %ld\t\t",raato,pvm);
          d=0;
       }
       else
          printf("%s\n\t\t",raato); /* kuolintapaan asti */
       pos++;
       pos2=0;
       while (raato[pos]) {
           raato[pos2]=raato[pos];
           pos++;
           pos2++; }
       raato[pos2]=0;
    }
    if (strlen(raato)==55)
       raato[54]=0;
 }
 printf("%-54s",raato);
 if (hp>0)
    printf("%3d",hp);
 else
    printf("  -");
 sprintf(raato,"[%d]",maxhp);
 printf("%6s\n",raato);
 if ((strncmp(syy,"quit",4)) && (strncmp(syy,"starvation",10)) && (!ascend))
 {   syy[0]=toupper(syy[0]);
     syy[strlen(syy)-1]=0;  /* replace the LF  */
    if (d)
       printf(" %ld",pvm);
    printf("\t\t%s.\n",syy);
 }
 (*num)++;
 return (score);
}

int error(argv_0,argv_i)
char *argv_0;
char *argv_i;
{ printf("This is %s, version %s.\n",argv_0,VERSION);
  printf("List the Nethack record file and calculate the average score.\n\n");
  printf("Usage: %s [-f file] [-l] [-u name] [-abcehkprstvw] [-n] [-d]\n\n",argv_0);
  printf("The options are the following:\n\n");
  printf("  -f file        to read the scores from file \"filename\"\n");
  printf("  -l             to read the scores from the logfile\n");
  printf("  -u name        to list only the scores of player \"name\"\n");
  printf("  -abcehkprstvw  to list only the scores for one class\n");
  printf("  -n number      to list only a given number of scores\n");
  printf("  -d             to show the dates as well\n\n");
  printf("You may specify any combination of these in any order.\n");
  printf("The space after -f, -u or -n is optional.\n");
  printf("The output may also be redirected with '>' or '|'.\n\n");
  printf("Unknown parameter %s\n",argv_i);
  exit(1);
}
