1*41234Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2*41234Sbostic /* hack.end.c - version 1.0.3 */ 3*41234Sbostic 4*41234Sbostic #include "hack.h" 5*41234Sbostic #include <stdio.h> 6*41234Sbostic #include <signal.h> 7*41234Sbostic #define Sprintf (void) sprintf 8*41234Sbostic extern char plname[], pl_character[]; 9*41234Sbostic extern char *itoa(), *ordin(), *eos(); 10*41234Sbostic 11*41234Sbostic xchar maxdlevel = 1; 12*41234Sbostic 13*41234Sbostic done1() 14*41234Sbostic { 15*41234Sbostic (void) signal(SIGINT,SIG_IGN); 16*41234Sbostic pline("Really quit?"); 17*41234Sbostic if(readchar() != 'y') { 18*41234Sbostic (void) signal(SIGINT,done1); 19*41234Sbostic clrlin(); 20*41234Sbostic (void) fflush(stdout); 21*41234Sbostic if(multi > 0) nomul(0); 22*41234Sbostic return(0); 23*41234Sbostic } 24*41234Sbostic done("quit"); 25*41234Sbostic /* NOTREACHED */ 26*41234Sbostic } 27*41234Sbostic 28*41234Sbostic int done_stopprint; 29*41234Sbostic int done_hup; 30*41234Sbostic 31*41234Sbostic done_intr(){ 32*41234Sbostic done_stopprint++; 33*41234Sbostic (void) signal(SIGINT, SIG_IGN); 34*41234Sbostic (void) signal(SIGQUIT, SIG_IGN); 35*41234Sbostic } 36*41234Sbostic 37*41234Sbostic done_hangup(){ 38*41234Sbostic done_hup++; 39*41234Sbostic (void) signal(SIGHUP, SIG_IGN); 40*41234Sbostic done_intr(); 41*41234Sbostic } 42*41234Sbostic 43*41234Sbostic done_in_by(mtmp) register struct monst *mtmp; { 44*41234Sbostic static char buf[BUFSZ]; 45*41234Sbostic pline("You die ..."); 46*41234Sbostic if(mtmp->data->mlet == ' '){ 47*41234Sbostic Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra); 48*41234Sbostic killer = buf; 49*41234Sbostic } else if(mtmp->mnamelth) { 50*41234Sbostic Sprintf(buf, "%s called %s", 51*41234Sbostic mtmp->data->mname, NAME(mtmp)); 52*41234Sbostic killer = buf; 53*41234Sbostic } else if(mtmp->minvis) { 54*41234Sbostic Sprintf(buf, "invisible %s", mtmp->data->mname); 55*41234Sbostic killer = buf; 56*41234Sbostic } else killer = mtmp->data->mname; 57*41234Sbostic done("died"); 58*41234Sbostic } 59*41234Sbostic 60*41234Sbostic /* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked", 61*41234Sbostic "burned", "starved" or "tricked" */ 62*41234Sbostic /* Be careful not to call panic from here! */ 63*41234Sbostic done(st1) 64*41234Sbostic register char *st1; 65*41234Sbostic { 66*41234Sbostic 67*41234Sbostic #ifdef WIZARD 68*41234Sbostic if(wizard && *st1 == 'd'){ 69*41234Sbostic u.uswldtim = 0; 70*41234Sbostic if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */ 71*41234Sbostic u.uhp = u.uhpmax; 72*41234Sbostic pline("For some reason you are still alive."); 73*41234Sbostic flags.move = 0; 74*41234Sbostic if(multi > 0) multi = 0; else multi = -1; 75*41234Sbostic flags.botl = 1; 76*41234Sbostic return; 77*41234Sbostic } 78*41234Sbostic #endif WIZARD 79*41234Sbostic (void) signal(SIGINT, done_intr); 80*41234Sbostic (void) signal(SIGQUIT, done_intr); 81*41234Sbostic (void) signal(SIGHUP, done_hangup); 82*41234Sbostic if(*st1 == 'q' && u.uhp < 1){ 83*41234Sbostic st1 = "died"; 84*41234Sbostic killer = "quit while already on Charon's boat"; 85*41234Sbostic } 86*41234Sbostic if(*st1 == 's') killer = "starvation"; else 87*41234Sbostic if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else 88*41234Sbostic if(*st1 == 'p') killer = "panic"; else 89*41234Sbostic if(*st1 == 't') killer = "trickery"; else 90*41234Sbostic if(!index("bcd", *st1)) killer = st1; 91*41234Sbostic paybill(); 92*41234Sbostic clearlocks(); 93*41234Sbostic if(flags.toplin == 1) more(); 94*41234Sbostic if(index("bcds", *st1)){ 95*41234Sbostic #ifdef WIZARD 96*41234Sbostic if(!wizard) 97*41234Sbostic #endif WIZARD 98*41234Sbostic savebones(); 99*41234Sbostic if(!flags.notombstone) 100*41234Sbostic outrip(); 101*41234Sbostic } 102*41234Sbostic if(*st1 == 'c') killer = st1; /* after outrip() */ 103*41234Sbostic settty((char *) 0); /* does a clear_screen() */ 104*41234Sbostic if(!done_stopprint) 105*41234Sbostic printf("Goodbye %s %s...\n\n", pl_character, plname); 106*41234Sbostic { long int tmp; 107*41234Sbostic tmp = u.ugold - u.ugold0; 108*41234Sbostic if(tmp < 0) 109*41234Sbostic tmp = 0; 110*41234Sbostic if(*st1 == 'd' || *st1 == 'b') 111*41234Sbostic tmp -= tmp/10; 112*41234Sbostic u.urexp += tmp; 113*41234Sbostic u.urexp += 50 * maxdlevel; 114*41234Sbostic if(maxdlevel > 20) 115*41234Sbostic u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20); 116*41234Sbostic } 117*41234Sbostic if(*st1 == 'e') { 118*41234Sbostic extern struct monst *mydogs; 119*41234Sbostic register struct monst *mtmp; 120*41234Sbostic register struct obj *otmp; 121*41234Sbostic register int i; 122*41234Sbostic register unsigned worthlessct = 0; 123*41234Sbostic boolean has_amulet = FALSE; 124*41234Sbostic 125*41234Sbostic killer = st1; 126*41234Sbostic keepdogs(); 127*41234Sbostic mtmp = mydogs; 128*41234Sbostic if(mtmp) { 129*41234Sbostic if(!done_stopprint) printf("You"); 130*41234Sbostic while(mtmp) { 131*41234Sbostic if(!done_stopprint) 132*41234Sbostic printf(" and %s", monnam(mtmp)); 133*41234Sbostic if(mtmp->mtame) 134*41234Sbostic u.urexp += mtmp->mhp; 135*41234Sbostic mtmp = mtmp->nmon; 136*41234Sbostic } 137*41234Sbostic if(!done_stopprint) 138*41234Sbostic printf("\nescaped from the dungeon with %ld points,\n", 139*41234Sbostic u.urexp); 140*41234Sbostic } else 141*41234Sbostic if(!done_stopprint) 142*41234Sbostic printf("You escaped from the dungeon with %ld points,\n", 143*41234Sbostic u.urexp); 144*41234Sbostic for(otmp = invent; otmp; otmp = otmp->nobj) { 145*41234Sbostic if(otmp->olet == GEM_SYM){ 146*41234Sbostic objects[otmp->otyp].oc_name_known = 1; 147*41234Sbostic i = otmp->quan*objects[otmp->otyp].g_val; 148*41234Sbostic if(i == 0) { 149*41234Sbostic worthlessct += otmp->quan; 150*41234Sbostic continue; 151*41234Sbostic } 152*41234Sbostic u.urexp += i; 153*41234Sbostic if(!done_stopprint) 154*41234Sbostic printf("\t%s (worth %d Zorkmids),\n", 155*41234Sbostic doname(otmp), i); 156*41234Sbostic } else if(otmp->olet == AMULET_SYM) { 157*41234Sbostic otmp->known = 1; 158*41234Sbostic i = (otmp->spe < 0) ? 2 : 5000; 159*41234Sbostic u.urexp += i; 160*41234Sbostic if(!done_stopprint) 161*41234Sbostic printf("\t%s (worth %d Zorkmids),\n", 162*41234Sbostic doname(otmp), i); 163*41234Sbostic if(otmp->spe >= 0) { 164*41234Sbostic has_amulet = TRUE; 165*41234Sbostic killer = "escaped (with amulet)"; 166*41234Sbostic } 167*41234Sbostic } 168*41234Sbostic } 169*41234Sbostic if(worthlessct) if(!done_stopprint) 170*41234Sbostic printf("\t%u worthless piece%s of coloured glass,\n", 171*41234Sbostic worthlessct, plur(worthlessct)); 172*41234Sbostic if(has_amulet) u.urexp *= 2; 173*41234Sbostic } else 174*41234Sbostic if(!done_stopprint) 175*41234Sbostic printf("You %s on dungeon level %d with %ld points,\n", 176*41234Sbostic st1, dlevel, u.urexp); 177*41234Sbostic if(!done_stopprint) 178*41234Sbostic printf("and %ld piece%s of gold, after %ld move%s.\n", 179*41234Sbostic u.ugold, plur(u.ugold), moves, plur(moves)); 180*41234Sbostic if(!done_stopprint) 181*41234Sbostic printf("You were level %u with a maximum of %d hit points when you %s.\n", 182*41234Sbostic u.ulevel, u.uhpmax, st1); 183*41234Sbostic if(*st1 == 'e' && !done_stopprint){ 184*41234Sbostic getret(); /* all those pieces of coloured glass ... */ 185*41234Sbostic cls(); 186*41234Sbostic } 187*41234Sbostic #ifdef WIZARD 188*41234Sbostic if(!wizard) 189*41234Sbostic #endif WIZARD 190*41234Sbostic topten(); 191*41234Sbostic if(done_stopprint) printf("\n\n"); 192*41234Sbostic exit(0); 193*41234Sbostic } 194*41234Sbostic 195*41234Sbostic #define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry)) 196*41234Sbostic #define NAMSZ 8 197*41234Sbostic #define DTHSZ 40 198*41234Sbostic #define PERSMAX 1 199*41234Sbostic #define POINTSMIN 1 /* must be > 0 */ 200*41234Sbostic #define ENTRYMAX 100 /* must be >= 10 */ 201*41234Sbostic #define PERS_IS_UID /* delete for PERSMAX per name; now per uid */ 202*41234Sbostic struct toptenentry { 203*41234Sbostic struct toptenentry *tt_next; 204*41234Sbostic long int points; 205*41234Sbostic int level,maxlvl,hp,maxhp; 206*41234Sbostic int uid; 207*41234Sbostic char plchar; 208*41234Sbostic char sex; 209*41234Sbostic char name[NAMSZ+1]; 210*41234Sbostic char death[DTHSZ+1]; 211*41234Sbostic char date[7]; /* yymmdd */ 212*41234Sbostic } *tt_head; 213*41234Sbostic 214*41234Sbostic topten(){ 215*41234Sbostic int uid = getuid(); 216*41234Sbostic int rank, rank0 = -1, rank1 = 0; 217*41234Sbostic int occ_cnt = PERSMAX; 218*41234Sbostic register struct toptenentry *t0, *t1, *tprev; 219*41234Sbostic char *recfile = RECORD; 220*41234Sbostic char *reclock = "record_lock"; 221*41234Sbostic int sleepct = 300; 222*41234Sbostic FILE *rfile; 223*41234Sbostic register flg = 0; 224*41234Sbostic extern char *getdate(); 225*41234Sbostic #define HUP if(!done_hup) 226*41234Sbostic while(link(recfile, reclock) == -1) { 227*41234Sbostic HUP perror(reclock); 228*41234Sbostic if(!sleepct--) { 229*41234Sbostic HUP puts("I give up. Sorry."); 230*41234Sbostic HUP puts("Perhaps there is an old record_lock around?"); 231*41234Sbostic return; 232*41234Sbostic } 233*41234Sbostic HUP printf("Waiting for access to record file. (%d)\n", 234*41234Sbostic sleepct); 235*41234Sbostic HUP (void) fflush(stdout); 236*41234Sbostic sleep(1); 237*41234Sbostic } 238*41234Sbostic if(!(rfile = fopen(recfile,"r"))){ 239*41234Sbostic HUP puts("Cannot open record file!"); 240*41234Sbostic goto unlock; 241*41234Sbostic } 242*41234Sbostic HUP (void) putchar('\n'); 243*41234Sbostic 244*41234Sbostic /* create a new 'topten' entry */ 245*41234Sbostic t0 = newttentry(); 246*41234Sbostic t0->level = dlevel; 247*41234Sbostic t0->maxlvl = maxdlevel; 248*41234Sbostic t0->hp = u.uhp; 249*41234Sbostic t0->maxhp = u.uhpmax; 250*41234Sbostic t0->points = u.urexp; 251*41234Sbostic t0->plchar = pl_character[0]; 252*41234Sbostic t0->sex = (flags.female ? 'F' : 'M'); 253*41234Sbostic t0->uid = uid; 254*41234Sbostic (void) strncpy(t0->name, plname, NAMSZ); 255*41234Sbostic (t0->name)[NAMSZ] = 0; 256*41234Sbostic (void) strncpy(t0->death, killer, DTHSZ); 257*41234Sbostic (t0->death)[DTHSZ] = 0; 258*41234Sbostic (void) strcpy(t0->date, getdate()); 259*41234Sbostic 260*41234Sbostic /* assure minimum number of points */ 261*41234Sbostic if(t0->points < POINTSMIN) 262*41234Sbostic t0->points = 0; 263*41234Sbostic 264*41234Sbostic t1 = tt_head = newttentry(); 265*41234Sbostic tprev = 0; 266*41234Sbostic /* rank0: -1 undefined, 0 not_on_list, n n_th on list */ 267*41234Sbostic for(rank = 1; ; ) { 268*41234Sbostic if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]", 269*41234Sbostic t1->date, &t1->uid, 270*41234Sbostic &t1->level, &t1->maxlvl, 271*41234Sbostic &t1->hp, &t1->maxhp, &t1->points, 272*41234Sbostic &t1->plchar, &t1->sex, t1->name, t1->death) != 11 273*41234Sbostic || t1->points < POINTSMIN) 274*41234Sbostic t1->points = 0; 275*41234Sbostic if(rank0 < 0 && t1->points < t0->points) { 276*41234Sbostic rank0 = rank++; 277*41234Sbostic if(tprev == 0) 278*41234Sbostic tt_head = t0; 279*41234Sbostic else 280*41234Sbostic tprev->tt_next = t0; 281*41234Sbostic t0->tt_next = t1; 282*41234Sbostic occ_cnt--; 283*41234Sbostic flg++; /* ask for a rewrite */ 284*41234Sbostic } else 285*41234Sbostic tprev = t1; 286*41234Sbostic if(t1->points == 0) break; 287*41234Sbostic if( 288*41234Sbostic #ifdef PERS_IS_UID 289*41234Sbostic t1->uid == t0->uid && 290*41234Sbostic #else 291*41234Sbostic strncmp(t1->name, t0->name, NAMSZ) == 0 && 292*41234Sbostic #endif PERS_IS_UID 293*41234Sbostic t1->plchar == t0->plchar && --occ_cnt <= 0){ 294*41234Sbostic if(rank0 < 0){ 295*41234Sbostic rank0 = 0; 296*41234Sbostic rank1 = rank; 297*41234Sbostic HUP printf("You didn't beat your previous score of %ld points.\n\n", 298*41234Sbostic t1->points); 299*41234Sbostic } 300*41234Sbostic if(occ_cnt < 0){ 301*41234Sbostic flg++; 302*41234Sbostic continue; 303*41234Sbostic } 304*41234Sbostic } 305*41234Sbostic if(rank <= ENTRYMAX){ 306*41234Sbostic t1 = t1->tt_next = newttentry(); 307*41234Sbostic rank++; 308*41234Sbostic } 309*41234Sbostic if(rank > ENTRYMAX){ 310*41234Sbostic t1->points = 0; 311*41234Sbostic break; 312*41234Sbostic } 313*41234Sbostic } 314*41234Sbostic if(flg) { /* rewrite record file */ 315*41234Sbostic (void) fclose(rfile); 316*41234Sbostic if(!(rfile = fopen(recfile,"w"))){ 317*41234Sbostic HUP puts("Cannot write record file\n"); 318*41234Sbostic goto unlock; 319*41234Sbostic } 320*41234Sbostic 321*41234Sbostic if(!done_stopprint) if(rank0 > 0){ 322*41234Sbostic if(rank0 <= 10) 323*41234Sbostic puts("You made the top ten list!\n"); 324*41234Sbostic else 325*41234Sbostic printf("You reached the %d%s place on the top %d list.\n\n", 326*41234Sbostic rank0, ordin(rank0), ENTRYMAX); 327*41234Sbostic } 328*41234Sbostic } 329*41234Sbostic if(rank0 == 0) rank0 = rank1; 330*41234Sbostic if(rank0 <= 0) rank0 = rank; 331*41234Sbostic if(!done_stopprint) outheader(); 332*41234Sbostic t1 = tt_head; 333*41234Sbostic for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) { 334*41234Sbostic if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n", 335*41234Sbostic t1->date, t1->uid, 336*41234Sbostic t1->level, t1->maxlvl, 337*41234Sbostic t1->hp, t1->maxhp, t1->points, 338*41234Sbostic t1->plchar, t1->sex, t1->name, t1->death); 339*41234Sbostic if(done_stopprint) continue; 340*41234Sbostic if(rank > flags.end_top && 341*41234Sbostic (rank < rank0-flags.end_around || rank > rank0+flags.end_around) 342*41234Sbostic && (!flags.end_own || 343*41234Sbostic #ifdef PERS_IS_UID 344*41234Sbostic t1->uid != t0->uid )) 345*41234Sbostic #else 346*41234Sbostic strncmp(t1->name, t0->name, NAMSZ))) 347*41234Sbostic #endif PERS_IS_UID 348*41234Sbostic continue; 349*41234Sbostic if(rank == rank0-flags.end_around && 350*41234Sbostic rank0 > flags.end_top+flags.end_around+1 && 351*41234Sbostic !flags.end_own) 352*41234Sbostic (void) putchar('\n'); 353*41234Sbostic if(rank != rank0) 354*41234Sbostic (void) outentry(rank, t1, 0); 355*41234Sbostic else if(!rank1) 356*41234Sbostic (void) outentry(rank, t1, 1); 357*41234Sbostic else { 358*41234Sbostic int t0lth = outentry(0, t0, -1); 359*41234Sbostic int t1lth = outentry(rank, t1, t0lth); 360*41234Sbostic if(t1lth > t0lth) t0lth = t1lth; 361*41234Sbostic (void) outentry(0, t0, t0lth); 362*41234Sbostic } 363*41234Sbostic } 364*41234Sbostic if(rank0 >= rank) if(!done_stopprint) 365*41234Sbostic (void) outentry(0, t0, 1); 366*41234Sbostic (void) fclose(rfile); 367*41234Sbostic unlock: 368*41234Sbostic (void) unlink(reclock); 369*41234Sbostic } 370*41234Sbostic 371*41234Sbostic outheader() { 372*41234Sbostic char linebuf[BUFSZ]; 373*41234Sbostic register char *bp; 374*41234Sbostic (void) strcpy(linebuf, "Number Points Name"); 375*41234Sbostic bp = eos(linebuf); 376*41234Sbostic while(bp < linebuf + COLNO - 9) *bp++ = ' '; 377*41234Sbostic (void) strcpy(bp, "Hp [max]"); 378*41234Sbostic puts(linebuf); 379*41234Sbostic } 380*41234Sbostic 381*41234Sbostic /* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */ 382*41234Sbostic int 383*41234Sbostic outentry(rank,t1,so) register struct toptenentry *t1; { 384*41234Sbostic boolean quit = FALSE, killed = FALSE, starv = FALSE; 385*41234Sbostic char linebuf[BUFSZ]; 386*41234Sbostic linebuf[0] = 0; 387*41234Sbostic if(rank) Sprintf(eos(linebuf), "%3d", rank); 388*41234Sbostic else Sprintf(eos(linebuf), " "); 389*41234Sbostic Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name); 390*41234Sbostic if(t1->plchar == 'X') Sprintf(eos(linebuf), " "); 391*41234Sbostic else Sprintf(eos(linebuf), "-%c ", t1->plchar); 392*41234Sbostic if(!strncmp("escaped", t1->death, 7)) { 393*41234Sbostic if(!strcmp(" (with amulet)", t1->death+7)) 394*41234Sbostic Sprintf(eos(linebuf), "escaped the dungeon with amulet"); 395*41234Sbostic else 396*41234Sbostic Sprintf(eos(linebuf), "escaped the dungeon [max level %d]", 397*41234Sbostic t1->maxlvl); 398*41234Sbostic } else { 399*41234Sbostic if(!strncmp(t1->death,"quit",4)) { 400*41234Sbostic quit = TRUE; 401*41234Sbostic if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4) 402*41234Sbostic Sprintf(eos(linebuf), "cravenly gave up"); 403*41234Sbostic else 404*41234Sbostic Sprintf(eos(linebuf), "quit"); 405*41234Sbostic } 406*41234Sbostic else if(!strcmp(t1->death,"choked")) 407*41234Sbostic Sprintf(eos(linebuf), "choked on %s food", 408*41234Sbostic (t1->sex == 'F') ? "her" : "his"); 409*41234Sbostic else if(!strncmp(t1->death,"starv",5)) 410*41234Sbostic Sprintf(eos(linebuf), "starved to death"), starv = TRUE; 411*41234Sbostic else Sprintf(eos(linebuf), "was killed"), killed = TRUE; 412*41234Sbostic Sprintf(eos(linebuf), " on%s level %d", 413*41234Sbostic (killed || starv) ? "" : " dungeon", t1->level); 414*41234Sbostic if(t1->maxlvl != t1->level) 415*41234Sbostic Sprintf(eos(linebuf), " [max %d]", t1->maxlvl); 416*41234Sbostic if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4); 417*41234Sbostic } 418*41234Sbostic if(killed) Sprintf(eos(linebuf), " by %s%s", 419*41234Sbostic (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4)) 420*41234Sbostic ? "" : 421*41234Sbostic index(vowels,*t1->death) ? "an " : "a ", 422*41234Sbostic t1->death); 423*41234Sbostic Sprintf(eos(linebuf), "."); 424*41234Sbostic if(t1->maxhp) { 425*41234Sbostic register char *bp = eos(linebuf); 426*41234Sbostic char hpbuf[10]; 427*41234Sbostic int hppos; 428*41234Sbostic Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-"); 429*41234Sbostic hppos = COLNO - 7 - strlen(hpbuf); 430*41234Sbostic if(bp <= linebuf + hppos) { 431*41234Sbostic while(bp < linebuf + hppos) *bp++ = ' '; 432*41234Sbostic (void) strcpy(bp, hpbuf); 433*41234Sbostic Sprintf(eos(bp), " [%d]", t1->maxhp); 434*41234Sbostic } 435*41234Sbostic } 436*41234Sbostic if(so == 0) puts(linebuf); 437*41234Sbostic else if(so > 0) { 438*41234Sbostic register char *bp = eos(linebuf); 439*41234Sbostic if(so >= COLNO) so = COLNO-1; 440*41234Sbostic while(bp < linebuf + so) *bp++ = ' '; 441*41234Sbostic *bp = 0; 442*41234Sbostic standoutbeg(); 443*41234Sbostic fputs(linebuf,stdout); 444*41234Sbostic standoutend(); 445*41234Sbostic (void) putchar('\n'); 446*41234Sbostic } 447*41234Sbostic return(strlen(linebuf)); 448*41234Sbostic } 449*41234Sbostic 450*41234Sbostic char * 451*41234Sbostic itoa(a) int a; { 452*41234Sbostic static char buf[12]; 453*41234Sbostic Sprintf(buf,"%d",a); 454*41234Sbostic return(buf); 455*41234Sbostic } 456*41234Sbostic 457*41234Sbostic char * 458*41234Sbostic ordin(n) int n; { 459*41234Sbostic register int d = n%10; 460*41234Sbostic return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" : 461*41234Sbostic (d==2) ? "nd" : "rd"); 462*41234Sbostic } 463*41234Sbostic 464*41234Sbostic clearlocks(){ 465*41234Sbostic register x; 466*41234Sbostic (void) signal(SIGHUP,SIG_IGN); 467*41234Sbostic for(x = maxdlevel; x >= 0; x--) { 468*41234Sbostic glo(x); 469*41234Sbostic (void) unlink(lock); /* not all levels need be present */ 470*41234Sbostic } 471*41234Sbostic } 472*41234Sbostic 473*41234Sbostic #ifdef NOSAVEONHANGUP 474*41234Sbostic hangup() 475*41234Sbostic { 476*41234Sbostic (void) signal(SIGINT, SIG_IGN); 477*41234Sbostic clearlocks(); 478*41234Sbostic exit(1); 479*41234Sbostic } 480*41234Sbostic #endif NOSAVEONHANGUP 481*41234Sbostic 482*41234Sbostic char * 483*41234Sbostic eos(s) 484*41234Sbostic register char *s; 485*41234Sbostic { 486*41234Sbostic while(*s) s++; 487*41234Sbostic return(s); 488*41234Sbostic } 489*41234Sbostic 490*41234Sbostic /* it is the callers responsibility to check that there is room for c */ 491*41234Sbostic charcat(s,c) register char *s, c; { 492*41234Sbostic while(*s) s++; 493*41234Sbostic *s++ = c; 494*41234Sbostic *s = 0; 495*41234Sbostic } 496*41234Sbostic 497*41234Sbostic /* 498*41234Sbostic * Called with args from main if argc >= 0. In this case, list scores as 499*41234Sbostic * requested. Otherwise, find scores for the current player (and list them 500*41234Sbostic * if argc == -1). 501*41234Sbostic */ 502*41234Sbostic prscore(argc,argv) int argc; char **argv; { 503*41234Sbostic extern char *hname; 504*41234Sbostic char **players; 505*41234Sbostic int playerct; 506*41234Sbostic int rank; 507*41234Sbostic register struct toptenentry *t1, *t2; 508*41234Sbostic char *recfile = RECORD; 509*41234Sbostic FILE *rfile; 510*41234Sbostic register flg = 0; 511*41234Sbostic register int i; 512*41234Sbostic #ifdef nonsense 513*41234Sbostic long total_score = 0L; 514*41234Sbostic char totchars[10]; 515*41234Sbostic int totcharct = 0; 516*41234Sbostic #endif nonsense 517*41234Sbostic int outflg = (argc >= -1); 518*41234Sbostic #ifdef PERS_IS_UID 519*41234Sbostic int uid = -1; 520*41234Sbostic #else 521*41234Sbostic char *player0; 522*41234Sbostic #endif PERS_IS_UID 523*41234Sbostic 524*41234Sbostic if(!(rfile = fopen(recfile,"r"))){ 525*41234Sbostic puts("Cannot open record file!"); 526*41234Sbostic return; 527*41234Sbostic } 528*41234Sbostic 529*41234Sbostic if(argc > 1 && !strncmp(argv[1], "-s", 2)){ 530*41234Sbostic if(!argv[1][2]){ 531*41234Sbostic argc--; 532*41234Sbostic argv++; 533*41234Sbostic } else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) { 534*41234Sbostic argv[1]++; 535*41234Sbostic argv[1][0] = '-'; 536*41234Sbostic } else argv[1] += 2; 537*41234Sbostic } 538*41234Sbostic if(argc <= 1){ 539*41234Sbostic #ifdef PERS_IS_UID 540*41234Sbostic uid = getuid(); 541*41234Sbostic playerct = 0; 542*41234Sbostic #else 543*41234Sbostic player0 = plname; 544*41234Sbostic if(!*player0) 545*41234Sbostic player0 = "hackplayer"; 546*41234Sbostic playerct = 1; 547*41234Sbostic players = &player0; 548*41234Sbostic #endif PERS_IS_UID 549*41234Sbostic } else { 550*41234Sbostic playerct = --argc; 551*41234Sbostic players = ++argv; 552*41234Sbostic } 553*41234Sbostic if(outflg) putchar('\n'); 554*41234Sbostic 555*41234Sbostic t1 = tt_head = newttentry(); 556*41234Sbostic for(rank = 1; ; rank++) { 557*41234Sbostic if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]", 558*41234Sbostic t1->date, &t1->uid, 559*41234Sbostic &t1->level, &t1->maxlvl, 560*41234Sbostic &t1->hp, &t1->maxhp, &t1->points, 561*41234Sbostic &t1->plchar, &t1->sex, t1->name, t1->death) != 11) 562*41234Sbostic t1->points = 0; 563*41234Sbostic if(t1->points == 0) break; 564*41234Sbostic #ifdef PERS_IS_UID 565*41234Sbostic if(!playerct && t1->uid == uid) 566*41234Sbostic flg++; 567*41234Sbostic else 568*41234Sbostic #endif PERS_IS_UID 569*41234Sbostic for(i = 0; i < playerct; i++){ 570*41234Sbostic if(strcmp(players[i], "all") == 0 || 571*41234Sbostic strncmp(t1->name, players[i], NAMSZ) == 0 || 572*41234Sbostic (players[i][0] == '-' && 573*41234Sbostic players[i][1] == t1->plchar && 574*41234Sbostic players[i][2] == 0) || 575*41234Sbostic (digit(players[i][0]) && rank <= atoi(players[i]))) 576*41234Sbostic flg++; 577*41234Sbostic } 578*41234Sbostic t1 = t1->tt_next = newttentry(); 579*41234Sbostic } 580*41234Sbostic (void) fclose(rfile); 581*41234Sbostic if(!flg) { 582*41234Sbostic if(outflg) { 583*41234Sbostic printf("Cannot find any entries for "); 584*41234Sbostic if(playerct < 1) printf("you.\n"); 585*41234Sbostic else { 586*41234Sbostic if(playerct > 1) printf("any of "); 587*41234Sbostic for(i=0; i<playerct; i++) 588*41234Sbostic printf("%s%s", players[i], (i<playerct-1)?", ":".\n"); 589*41234Sbostic printf("Call is: %s -s [playernames]\n", hname); 590*41234Sbostic } 591*41234Sbostic } 592*41234Sbostic return; 593*41234Sbostic } 594*41234Sbostic 595*41234Sbostic if(outflg) outheader(); 596*41234Sbostic t1 = tt_head; 597*41234Sbostic for(rank = 1; t1->points != 0; rank++, t1 = t2) { 598*41234Sbostic t2 = t1->tt_next; 599*41234Sbostic #ifdef PERS_IS_UID 600*41234Sbostic if(!playerct && t1->uid == uid) 601*41234Sbostic goto outwithit; 602*41234Sbostic else 603*41234Sbostic #endif PERS_IS_UID 604*41234Sbostic for(i = 0; i < playerct; i++){ 605*41234Sbostic if(strcmp(players[i], "all") == 0 || 606*41234Sbostic strncmp(t1->name, players[i], NAMSZ) == 0 || 607*41234Sbostic (players[i][0] == '-' && 608*41234Sbostic players[i][1] == t1->plchar && 609*41234Sbostic players[i][2] == 0) || 610*41234Sbostic (digit(players[i][0]) && rank <= atoi(players[i]))){ 611*41234Sbostic outwithit: 612*41234Sbostic if(outflg) 613*41234Sbostic (void) outentry(rank, t1, 0); 614*41234Sbostic #ifdef nonsense 615*41234Sbostic total_score += t1->points; 616*41234Sbostic if(totcharct < sizeof(totchars)-1) 617*41234Sbostic totchars[totcharct++] = t1->plchar; 618*41234Sbostic #endif nonsense 619*41234Sbostic break; 620*41234Sbostic } 621*41234Sbostic } 622*41234Sbostic free((char *) t1); 623*41234Sbostic } 624*41234Sbostic #ifdef nonsense 625*41234Sbostic totchars[totcharct] = 0; 626*41234Sbostic 627*41234Sbostic /* We would like to determine whether he is experienced. However, 628*41234Sbostic the information collected here only tells about the scores/roles 629*41234Sbostic that got into the topten (top 100?). We should maintain a 630*41234Sbostic .hacklog or something in his home directory. */ 631*41234Sbostic flags.beginner = (total_score < 6000); 632*41234Sbostic for(i=0; i<6; i++) 633*41234Sbostic if(!index(totchars, "CFKSTWX"[i])) { 634*41234Sbostic flags.beginner = 1; 635*41234Sbostic if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i]; 636*41234Sbostic break; 637*41234Sbostic } 638*41234Sbostic #endif nonsense 639*41234Sbostic } 640