141234Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
241234Sbostic /* hack.end.c - version 1.0.3 */
341234Sbostic
441234Sbostic #include "hack.h"
541234Sbostic #include <stdio.h>
641234Sbostic #include <signal.h>
741234Sbostic #define Sprintf (void) sprintf
841234Sbostic extern char plname[], pl_character[];
941234Sbostic extern char *itoa(), *ordin(), *eos();
1041234Sbostic
1141234Sbostic xchar maxdlevel = 1;
1241234Sbostic
13*47700Sbostic void
done1()1441234Sbostic done1()
1541234Sbostic {
1641234Sbostic (void) signal(SIGINT,SIG_IGN);
1741234Sbostic pline("Really quit?");
1841234Sbostic if(readchar() != 'y') {
1941234Sbostic (void) signal(SIGINT,done1);
2041234Sbostic clrlin();
2141234Sbostic (void) fflush(stdout);
2241234Sbostic if(multi > 0) nomul(0);
23*47700Sbostic return;
2441234Sbostic }
2541234Sbostic done("quit");
2641234Sbostic /* NOTREACHED */
2741234Sbostic }
2841234Sbostic
2941234Sbostic int done_stopprint;
3041234Sbostic int done_hup;
3141234Sbostic
32*47700Sbostic void
done_intr()3341234Sbostic done_intr(){
3441234Sbostic done_stopprint++;
3541234Sbostic (void) signal(SIGINT, SIG_IGN);
3641234Sbostic (void) signal(SIGQUIT, SIG_IGN);
3741234Sbostic }
3841234Sbostic
39*47700Sbostic void
done_hangup()4041234Sbostic done_hangup(){
4141234Sbostic done_hup++;
4241234Sbostic (void) signal(SIGHUP, SIG_IGN);
4341234Sbostic done_intr();
4441234Sbostic }
4541234Sbostic
done_in_by(mtmp)4641234Sbostic done_in_by(mtmp) register struct monst *mtmp; {
4741234Sbostic static char buf[BUFSZ];
4841234Sbostic pline("You die ...");
4941234Sbostic if(mtmp->data->mlet == ' '){
5041234Sbostic Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra);
5141234Sbostic killer = buf;
5241234Sbostic } else if(mtmp->mnamelth) {
5341234Sbostic Sprintf(buf, "%s called %s",
5441234Sbostic mtmp->data->mname, NAME(mtmp));
5541234Sbostic killer = buf;
5641234Sbostic } else if(mtmp->minvis) {
5741234Sbostic Sprintf(buf, "invisible %s", mtmp->data->mname);
5841234Sbostic killer = buf;
5941234Sbostic } else killer = mtmp->data->mname;
6041234Sbostic done("died");
6141234Sbostic }
6241234Sbostic
6341234Sbostic /* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked",
6441234Sbostic "burned", "starved" or "tricked" */
6541234Sbostic /* Be careful not to call panic from here! */
done(st1)6641234Sbostic done(st1)
6741234Sbostic register char *st1;
6841234Sbostic {
6941234Sbostic
7041234Sbostic #ifdef WIZARD
7141234Sbostic if(wizard && *st1 == 'd'){
7241234Sbostic u.uswldtim = 0;
7341234Sbostic if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */
7441234Sbostic u.uhp = u.uhpmax;
7541234Sbostic pline("For some reason you are still alive.");
7641234Sbostic flags.move = 0;
7741234Sbostic if(multi > 0) multi = 0; else multi = -1;
7841234Sbostic flags.botl = 1;
7941234Sbostic return;
8041234Sbostic }
8141234Sbostic #endif WIZARD
8241234Sbostic (void) signal(SIGINT, done_intr);
8341234Sbostic (void) signal(SIGQUIT, done_intr);
8441234Sbostic (void) signal(SIGHUP, done_hangup);
8541234Sbostic if(*st1 == 'q' && u.uhp < 1){
8641234Sbostic st1 = "died";
8741234Sbostic killer = "quit while already on Charon's boat";
8841234Sbostic }
8941234Sbostic if(*st1 == 's') killer = "starvation"; else
9041234Sbostic if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else
9141234Sbostic if(*st1 == 'p') killer = "panic"; else
9241234Sbostic if(*st1 == 't') killer = "trickery"; else
9341234Sbostic if(!index("bcd", *st1)) killer = st1;
9441234Sbostic paybill();
9541234Sbostic clearlocks();
9641234Sbostic if(flags.toplin == 1) more();
9741234Sbostic if(index("bcds", *st1)){
9841234Sbostic #ifdef WIZARD
9941234Sbostic if(!wizard)
10041234Sbostic #endif WIZARD
10141234Sbostic savebones();
10241234Sbostic if(!flags.notombstone)
10341234Sbostic outrip();
10441234Sbostic }
10541234Sbostic if(*st1 == 'c') killer = st1; /* after outrip() */
10641234Sbostic settty((char *) 0); /* does a clear_screen() */
10741234Sbostic if(!done_stopprint)
10841234Sbostic printf("Goodbye %s %s...\n\n", pl_character, plname);
10941234Sbostic { long int tmp;
11041234Sbostic tmp = u.ugold - u.ugold0;
11141234Sbostic if(tmp < 0)
11241234Sbostic tmp = 0;
11341234Sbostic if(*st1 == 'd' || *st1 == 'b')
11441234Sbostic tmp -= tmp/10;
11541234Sbostic u.urexp += tmp;
11641234Sbostic u.urexp += 50 * maxdlevel;
11741234Sbostic if(maxdlevel > 20)
11841234Sbostic u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20);
11941234Sbostic }
12041234Sbostic if(*st1 == 'e') {
12141234Sbostic extern struct monst *mydogs;
12241234Sbostic register struct monst *mtmp;
12341234Sbostic register struct obj *otmp;
12441234Sbostic register int i;
12541234Sbostic register unsigned worthlessct = 0;
12641234Sbostic boolean has_amulet = FALSE;
12741234Sbostic
12841234Sbostic killer = st1;
12941234Sbostic keepdogs();
13041234Sbostic mtmp = mydogs;
13141234Sbostic if(mtmp) {
13241234Sbostic if(!done_stopprint) printf("You");
13341234Sbostic while(mtmp) {
13441234Sbostic if(!done_stopprint)
13541234Sbostic printf(" and %s", monnam(mtmp));
13641234Sbostic if(mtmp->mtame)
13741234Sbostic u.urexp += mtmp->mhp;
13841234Sbostic mtmp = mtmp->nmon;
13941234Sbostic }
14041234Sbostic if(!done_stopprint)
14141234Sbostic printf("\nescaped from the dungeon with %ld points,\n",
14241234Sbostic u.urexp);
14341234Sbostic } else
14441234Sbostic if(!done_stopprint)
14541234Sbostic printf("You escaped from the dungeon with %ld points,\n",
14641234Sbostic u.urexp);
14741234Sbostic for(otmp = invent; otmp; otmp = otmp->nobj) {
14841234Sbostic if(otmp->olet == GEM_SYM){
14941234Sbostic objects[otmp->otyp].oc_name_known = 1;
15041234Sbostic i = otmp->quan*objects[otmp->otyp].g_val;
15141234Sbostic if(i == 0) {
15241234Sbostic worthlessct += otmp->quan;
15341234Sbostic continue;
15441234Sbostic }
15541234Sbostic u.urexp += i;
15641234Sbostic if(!done_stopprint)
15741234Sbostic printf("\t%s (worth %d Zorkmids),\n",
15841234Sbostic doname(otmp), i);
15941234Sbostic } else if(otmp->olet == AMULET_SYM) {
16041234Sbostic otmp->known = 1;
16141234Sbostic i = (otmp->spe < 0) ? 2 : 5000;
16241234Sbostic u.urexp += i;
16341234Sbostic if(!done_stopprint)
16441234Sbostic printf("\t%s (worth %d Zorkmids),\n",
16541234Sbostic doname(otmp), i);
16641234Sbostic if(otmp->spe >= 0) {
16741234Sbostic has_amulet = TRUE;
16841234Sbostic killer = "escaped (with amulet)";
16941234Sbostic }
17041234Sbostic }
17141234Sbostic }
17241234Sbostic if(worthlessct) if(!done_stopprint)
17341234Sbostic printf("\t%u worthless piece%s of coloured glass,\n",
17441234Sbostic worthlessct, plur(worthlessct));
17541234Sbostic if(has_amulet) u.urexp *= 2;
17641234Sbostic } else
17741234Sbostic if(!done_stopprint)
17841234Sbostic printf("You %s on dungeon level %d with %ld points,\n",
17941234Sbostic st1, dlevel, u.urexp);
18041234Sbostic if(!done_stopprint)
18141234Sbostic printf("and %ld piece%s of gold, after %ld move%s.\n",
18241234Sbostic u.ugold, plur(u.ugold), moves, plur(moves));
18341234Sbostic if(!done_stopprint)
18441234Sbostic printf("You were level %u with a maximum of %d hit points when you %s.\n",
18541234Sbostic u.ulevel, u.uhpmax, st1);
18641234Sbostic if(*st1 == 'e' && !done_stopprint){
18741234Sbostic getret(); /* all those pieces of coloured glass ... */
18841234Sbostic cls();
18941234Sbostic }
19041234Sbostic #ifdef WIZARD
19141234Sbostic if(!wizard)
19241234Sbostic #endif WIZARD
19341234Sbostic topten();
19441234Sbostic if(done_stopprint) printf("\n\n");
19541234Sbostic exit(0);
19641234Sbostic }
19741234Sbostic
19841234Sbostic #define newttentry() (struct toptenentry *) alloc(sizeof(struct toptenentry))
19941234Sbostic #define NAMSZ 8
20041234Sbostic #define DTHSZ 40
20141234Sbostic #define PERSMAX 1
20241234Sbostic #define POINTSMIN 1 /* must be > 0 */
20341234Sbostic #define ENTRYMAX 100 /* must be >= 10 */
20441234Sbostic #define PERS_IS_UID /* delete for PERSMAX per name; now per uid */
20541234Sbostic struct toptenentry {
20641234Sbostic struct toptenentry *tt_next;
20741234Sbostic long int points;
20841234Sbostic int level,maxlvl,hp,maxhp;
20941234Sbostic int uid;
21041234Sbostic char plchar;
21141234Sbostic char sex;
21241234Sbostic char name[NAMSZ+1];
21341234Sbostic char death[DTHSZ+1];
21441234Sbostic char date[7]; /* yymmdd */
21541234Sbostic } *tt_head;
21641234Sbostic
topten()21741234Sbostic topten(){
21841234Sbostic int uid = getuid();
21941234Sbostic int rank, rank0 = -1, rank1 = 0;
22041234Sbostic int occ_cnt = PERSMAX;
22141234Sbostic register struct toptenentry *t0, *t1, *tprev;
22241234Sbostic char *recfile = RECORD;
22341234Sbostic char *reclock = "record_lock";
22441234Sbostic int sleepct = 300;
22541234Sbostic FILE *rfile;
22641234Sbostic register flg = 0;
22741234Sbostic extern char *getdate();
22841234Sbostic #define HUP if(!done_hup)
22941234Sbostic while(link(recfile, reclock) == -1) {
23041234Sbostic HUP perror(reclock);
23141234Sbostic if(!sleepct--) {
23241234Sbostic HUP puts("I give up. Sorry.");
23341234Sbostic HUP puts("Perhaps there is an old record_lock around?");
23441234Sbostic return;
23541234Sbostic }
23641234Sbostic HUP printf("Waiting for access to record file. (%d)\n",
23741234Sbostic sleepct);
23841234Sbostic HUP (void) fflush(stdout);
23941234Sbostic sleep(1);
24041234Sbostic }
24141234Sbostic if(!(rfile = fopen(recfile,"r"))){
24241234Sbostic HUP puts("Cannot open record file!");
24341234Sbostic goto unlock;
24441234Sbostic }
24541234Sbostic HUP (void) putchar('\n');
24641234Sbostic
24741234Sbostic /* create a new 'topten' entry */
24841234Sbostic t0 = newttentry();
24941234Sbostic t0->level = dlevel;
25041234Sbostic t0->maxlvl = maxdlevel;
25141234Sbostic t0->hp = u.uhp;
25241234Sbostic t0->maxhp = u.uhpmax;
25341234Sbostic t0->points = u.urexp;
25441234Sbostic t0->plchar = pl_character[0];
25541234Sbostic t0->sex = (flags.female ? 'F' : 'M');
25641234Sbostic t0->uid = uid;
25741234Sbostic (void) strncpy(t0->name, plname, NAMSZ);
25841234Sbostic (t0->name)[NAMSZ] = 0;
25941234Sbostic (void) strncpy(t0->death, killer, DTHSZ);
26041234Sbostic (t0->death)[DTHSZ] = 0;
26141234Sbostic (void) strcpy(t0->date, getdate());
26241234Sbostic
26341234Sbostic /* assure minimum number of points */
26441234Sbostic if(t0->points < POINTSMIN)
26541234Sbostic t0->points = 0;
26641234Sbostic
26741234Sbostic t1 = tt_head = newttentry();
26841234Sbostic tprev = 0;
26941234Sbostic /* rank0: -1 undefined, 0 not_on_list, n n_th on list */
27041234Sbostic for(rank = 1; ; ) {
27141234Sbostic if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
27241234Sbostic t1->date, &t1->uid,
27341234Sbostic &t1->level, &t1->maxlvl,
27441234Sbostic &t1->hp, &t1->maxhp, &t1->points,
27541234Sbostic &t1->plchar, &t1->sex, t1->name, t1->death) != 11
27641234Sbostic || t1->points < POINTSMIN)
27741234Sbostic t1->points = 0;
27841234Sbostic if(rank0 < 0 && t1->points < t0->points) {
27941234Sbostic rank0 = rank++;
28041234Sbostic if(tprev == 0)
28141234Sbostic tt_head = t0;
28241234Sbostic else
28341234Sbostic tprev->tt_next = t0;
28441234Sbostic t0->tt_next = t1;
28541234Sbostic occ_cnt--;
28641234Sbostic flg++; /* ask for a rewrite */
28741234Sbostic } else
28841234Sbostic tprev = t1;
28941234Sbostic if(t1->points == 0) break;
29041234Sbostic if(
29141234Sbostic #ifdef PERS_IS_UID
29241234Sbostic t1->uid == t0->uid &&
29341234Sbostic #else
29441234Sbostic strncmp(t1->name, t0->name, NAMSZ) == 0 &&
29541234Sbostic #endif PERS_IS_UID
29641234Sbostic t1->plchar == t0->plchar && --occ_cnt <= 0){
29741234Sbostic if(rank0 < 0){
29841234Sbostic rank0 = 0;
29941234Sbostic rank1 = rank;
30041234Sbostic HUP printf("You didn't beat your previous score of %ld points.\n\n",
30141234Sbostic t1->points);
30241234Sbostic }
30341234Sbostic if(occ_cnt < 0){
30441234Sbostic flg++;
30541234Sbostic continue;
30641234Sbostic }
30741234Sbostic }
30841234Sbostic if(rank <= ENTRYMAX){
30941234Sbostic t1 = t1->tt_next = newttentry();
31041234Sbostic rank++;
31141234Sbostic }
31241234Sbostic if(rank > ENTRYMAX){
31341234Sbostic t1->points = 0;
31441234Sbostic break;
31541234Sbostic }
31641234Sbostic }
31741234Sbostic if(flg) { /* rewrite record file */
31841234Sbostic (void) fclose(rfile);
31941234Sbostic if(!(rfile = fopen(recfile,"w"))){
32041234Sbostic HUP puts("Cannot write record file\n");
32141234Sbostic goto unlock;
32241234Sbostic }
32341234Sbostic
32441234Sbostic if(!done_stopprint) if(rank0 > 0){
32541234Sbostic if(rank0 <= 10)
32641234Sbostic puts("You made the top ten list!\n");
32741234Sbostic else
32841234Sbostic printf("You reached the %d%s place on the top %d list.\n\n",
32941234Sbostic rank0, ordin(rank0), ENTRYMAX);
33041234Sbostic }
33141234Sbostic }
33241234Sbostic if(rank0 == 0) rank0 = rank1;
33341234Sbostic if(rank0 <= 0) rank0 = rank;
33441234Sbostic if(!done_stopprint) outheader();
33541234Sbostic t1 = tt_head;
33641234Sbostic for(rank = 1; t1->points != 0; rank++, t1 = t1->tt_next) {
33741234Sbostic if(flg) fprintf(rfile,"%6s %d %d %d %d %d %ld %c%c %s,%s\n",
33841234Sbostic t1->date, t1->uid,
33941234Sbostic t1->level, t1->maxlvl,
34041234Sbostic t1->hp, t1->maxhp, t1->points,
34141234Sbostic t1->plchar, t1->sex, t1->name, t1->death);
34241234Sbostic if(done_stopprint) continue;
34341234Sbostic if(rank > flags.end_top &&
34441234Sbostic (rank < rank0-flags.end_around || rank > rank0+flags.end_around)
34541234Sbostic && (!flags.end_own ||
34641234Sbostic #ifdef PERS_IS_UID
34741234Sbostic t1->uid != t0->uid ))
34841234Sbostic #else
34941234Sbostic strncmp(t1->name, t0->name, NAMSZ)))
35041234Sbostic #endif PERS_IS_UID
35141234Sbostic continue;
35241234Sbostic if(rank == rank0-flags.end_around &&
35341234Sbostic rank0 > flags.end_top+flags.end_around+1 &&
35441234Sbostic !flags.end_own)
35541234Sbostic (void) putchar('\n');
35641234Sbostic if(rank != rank0)
35741234Sbostic (void) outentry(rank, t1, 0);
35841234Sbostic else if(!rank1)
35941234Sbostic (void) outentry(rank, t1, 1);
36041234Sbostic else {
36141234Sbostic int t0lth = outentry(0, t0, -1);
36241234Sbostic int t1lth = outentry(rank, t1, t0lth);
36341234Sbostic if(t1lth > t0lth) t0lth = t1lth;
36441234Sbostic (void) outentry(0, t0, t0lth);
36541234Sbostic }
36641234Sbostic }
36741234Sbostic if(rank0 >= rank) if(!done_stopprint)
36841234Sbostic (void) outentry(0, t0, 1);
36941234Sbostic (void) fclose(rfile);
37041234Sbostic unlock:
37141234Sbostic (void) unlink(reclock);
37241234Sbostic }
37341234Sbostic
outheader()37441234Sbostic outheader() {
37541234Sbostic char linebuf[BUFSZ];
37641234Sbostic register char *bp;
37741234Sbostic (void) strcpy(linebuf, "Number Points Name");
37841234Sbostic bp = eos(linebuf);
37941234Sbostic while(bp < linebuf + COLNO - 9) *bp++ = ' ';
38041234Sbostic (void) strcpy(bp, "Hp [max]");
38141234Sbostic puts(linebuf);
38241234Sbostic }
38341234Sbostic
38441234Sbostic /* so>0: standout line; so=0: ordinary line; so<0: no output, return lth */
38541234Sbostic int
outentry(rank,t1,so)38641234Sbostic outentry(rank,t1,so) register struct toptenentry *t1; {
38741234Sbostic boolean quit = FALSE, killed = FALSE, starv = FALSE;
38841234Sbostic char linebuf[BUFSZ];
38941234Sbostic linebuf[0] = 0;
39041234Sbostic if(rank) Sprintf(eos(linebuf), "%3d", rank);
39141234Sbostic else Sprintf(eos(linebuf), " ");
39241234Sbostic Sprintf(eos(linebuf), " %6ld %8s", t1->points, t1->name);
39341234Sbostic if(t1->plchar == 'X') Sprintf(eos(linebuf), " ");
39441234Sbostic else Sprintf(eos(linebuf), "-%c ", t1->plchar);
39541234Sbostic if(!strncmp("escaped", t1->death, 7)) {
39641234Sbostic if(!strcmp(" (with amulet)", t1->death+7))
39741234Sbostic Sprintf(eos(linebuf), "escaped the dungeon with amulet");
39841234Sbostic else
39941234Sbostic Sprintf(eos(linebuf), "escaped the dungeon [max level %d]",
40041234Sbostic t1->maxlvl);
40141234Sbostic } else {
40241234Sbostic if(!strncmp(t1->death,"quit",4)) {
40341234Sbostic quit = TRUE;
40441234Sbostic if(t1->maxhp < 3*t1->hp && t1->maxlvl < 4)
40541234Sbostic Sprintf(eos(linebuf), "cravenly gave up");
40641234Sbostic else
40741234Sbostic Sprintf(eos(linebuf), "quit");
40841234Sbostic }
40941234Sbostic else if(!strcmp(t1->death,"choked"))
41041234Sbostic Sprintf(eos(linebuf), "choked on %s food",
41141234Sbostic (t1->sex == 'F') ? "her" : "his");
41241234Sbostic else if(!strncmp(t1->death,"starv",5))
41341234Sbostic Sprintf(eos(linebuf), "starved to death"), starv = TRUE;
41441234Sbostic else Sprintf(eos(linebuf), "was killed"), killed = TRUE;
41541234Sbostic Sprintf(eos(linebuf), " on%s level %d",
41641234Sbostic (killed || starv) ? "" : " dungeon", t1->level);
41741234Sbostic if(t1->maxlvl != t1->level)
41841234Sbostic Sprintf(eos(linebuf), " [max %d]", t1->maxlvl);
41941234Sbostic if(quit && t1->death[4]) Sprintf(eos(linebuf), t1->death + 4);
42041234Sbostic }
42141234Sbostic if(killed) Sprintf(eos(linebuf), " by %s%s",
42241234Sbostic (!strncmp(t1->death, "trick", 5) || !strncmp(t1->death, "the ", 4))
42341234Sbostic ? "" :
42441234Sbostic index(vowels,*t1->death) ? "an " : "a ",
42541234Sbostic t1->death);
42641234Sbostic Sprintf(eos(linebuf), ".");
42741234Sbostic if(t1->maxhp) {
42841234Sbostic register char *bp = eos(linebuf);
42941234Sbostic char hpbuf[10];
43041234Sbostic int hppos;
43141234Sbostic Sprintf(hpbuf, (t1->hp > 0) ? itoa(t1->hp) : "-");
43241234Sbostic hppos = COLNO - 7 - strlen(hpbuf);
43341234Sbostic if(bp <= linebuf + hppos) {
43441234Sbostic while(bp < linebuf + hppos) *bp++ = ' ';
43541234Sbostic (void) strcpy(bp, hpbuf);
43641234Sbostic Sprintf(eos(bp), " [%d]", t1->maxhp);
43741234Sbostic }
43841234Sbostic }
43941234Sbostic if(so == 0) puts(linebuf);
44041234Sbostic else if(so > 0) {
44141234Sbostic register char *bp = eos(linebuf);
44241234Sbostic if(so >= COLNO) so = COLNO-1;
44341234Sbostic while(bp < linebuf + so) *bp++ = ' ';
44441234Sbostic *bp = 0;
44541234Sbostic standoutbeg();
44641234Sbostic fputs(linebuf,stdout);
44741234Sbostic standoutend();
44841234Sbostic (void) putchar('\n');
44941234Sbostic }
45041234Sbostic return(strlen(linebuf));
45141234Sbostic }
45241234Sbostic
45341234Sbostic char *
itoa(a)45441234Sbostic itoa(a) int a; {
45541234Sbostic static char buf[12];
45641234Sbostic Sprintf(buf,"%d",a);
45741234Sbostic return(buf);
45841234Sbostic }
45941234Sbostic
46041234Sbostic char *
ordin(n)46141234Sbostic ordin(n) int n; {
46241234Sbostic register int d = n%10;
46341234Sbostic return((d==0 || d>3 || n/10==1) ? "th" : (d==1) ? "st" :
46441234Sbostic (d==2) ? "nd" : "rd");
46541234Sbostic }
46641234Sbostic
clearlocks()46741234Sbostic clearlocks(){
46841234Sbostic register x;
46941234Sbostic (void) signal(SIGHUP,SIG_IGN);
47041234Sbostic for(x = maxdlevel; x >= 0; x--) {
47141234Sbostic glo(x);
47241234Sbostic (void) unlink(lock); /* not all levels need be present */
47341234Sbostic }
47441234Sbostic }
47541234Sbostic
47641234Sbostic #ifdef NOSAVEONHANGUP
hangup()47741234Sbostic hangup()
47841234Sbostic {
47941234Sbostic (void) signal(SIGINT, SIG_IGN);
48041234Sbostic clearlocks();
48141234Sbostic exit(1);
48241234Sbostic }
48341234Sbostic #endif NOSAVEONHANGUP
48441234Sbostic
48541234Sbostic char *
eos(s)48641234Sbostic eos(s)
48741234Sbostic register char *s;
48841234Sbostic {
48941234Sbostic while(*s) s++;
49041234Sbostic return(s);
49141234Sbostic }
49241234Sbostic
49341234Sbostic /* it is the callers responsibility to check that there is room for c */
charcat(s,c)49441234Sbostic charcat(s,c) register char *s, c; {
49541234Sbostic while(*s) s++;
49641234Sbostic *s++ = c;
49741234Sbostic *s = 0;
49841234Sbostic }
49941234Sbostic
50041234Sbostic /*
50141234Sbostic * Called with args from main if argc >= 0. In this case, list scores as
50241234Sbostic * requested. Otherwise, find scores for the current player (and list them
50341234Sbostic * if argc == -1).
50441234Sbostic */
prscore(argc,argv)50541234Sbostic prscore(argc,argv) int argc; char **argv; {
50641234Sbostic extern char *hname;
50741234Sbostic char **players;
50841234Sbostic int playerct;
50941234Sbostic int rank;
51041234Sbostic register struct toptenentry *t1, *t2;
51141234Sbostic char *recfile = RECORD;
51241234Sbostic FILE *rfile;
51341234Sbostic register flg = 0;
51441234Sbostic register int i;
51541234Sbostic #ifdef nonsense
51641234Sbostic long total_score = 0L;
51741234Sbostic char totchars[10];
51841234Sbostic int totcharct = 0;
51941234Sbostic #endif nonsense
52041234Sbostic int outflg = (argc >= -1);
52141234Sbostic #ifdef PERS_IS_UID
52241234Sbostic int uid = -1;
52341234Sbostic #else
52441234Sbostic char *player0;
52541234Sbostic #endif PERS_IS_UID
52641234Sbostic
52741234Sbostic if(!(rfile = fopen(recfile,"r"))){
52841234Sbostic puts("Cannot open record file!");
52941234Sbostic return;
53041234Sbostic }
53141234Sbostic
53241234Sbostic if(argc > 1 && !strncmp(argv[1], "-s", 2)){
53341234Sbostic if(!argv[1][2]){
53441234Sbostic argc--;
53541234Sbostic argv++;
53641234Sbostic } else if(!argv[1][3] && index("CFKSTWX", argv[1][2])) {
53741234Sbostic argv[1]++;
53841234Sbostic argv[1][0] = '-';
53941234Sbostic } else argv[1] += 2;
54041234Sbostic }
54141234Sbostic if(argc <= 1){
54241234Sbostic #ifdef PERS_IS_UID
54341234Sbostic uid = getuid();
54441234Sbostic playerct = 0;
54541234Sbostic #else
54641234Sbostic player0 = plname;
54741234Sbostic if(!*player0)
54841234Sbostic player0 = "hackplayer";
54941234Sbostic playerct = 1;
55041234Sbostic players = &player0;
55141234Sbostic #endif PERS_IS_UID
55241234Sbostic } else {
55341234Sbostic playerct = --argc;
55441234Sbostic players = ++argv;
55541234Sbostic }
55641234Sbostic if(outflg) putchar('\n');
55741234Sbostic
55841234Sbostic t1 = tt_head = newttentry();
55941234Sbostic for(rank = 1; ; rank++) {
56041234Sbostic if(fscanf(rfile, "%6s %d %d %d %d %d %ld %c%c %[^,],%[^\n]",
56141234Sbostic t1->date, &t1->uid,
56241234Sbostic &t1->level, &t1->maxlvl,
56341234Sbostic &t1->hp, &t1->maxhp, &t1->points,
56441234Sbostic &t1->plchar, &t1->sex, t1->name, t1->death) != 11)
56541234Sbostic t1->points = 0;
56641234Sbostic if(t1->points == 0) break;
56741234Sbostic #ifdef PERS_IS_UID
56841234Sbostic if(!playerct && t1->uid == uid)
56941234Sbostic flg++;
57041234Sbostic else
57141234Sbostic #endif PERS_IS_UID
57241234Sbostic for(i = 0; i < playerct; i++){
57341234Sbostic if(strcmp(players[i], "all") == 0 ||
57441234Sbostic strncmp(t1->name, players[i], NAMSZ) == 0 ||
57541234Sbostic (players[i][0] == '-' &&
57641234Sbostic players[i][1] == t1->plchar &&
57741234Sbostic players[i][2] == 0) ||
57841234Sbostic (digit(players[i][0]) && rank <= atoi(players[i])))
57941234Sbostic flg++;
58041234Sbostic }
58141234Sbostic t1 = t1->tt_next = newttentry();
58241234Sbostic }
58341234Sbostic (void) fclose(rfile);
58441234Sbostic if(!flg) {
58541234Sbostic if(outflg) {
58641234Sbostic printf("Cannot find any entries for ");
58741234Sbostic if(playerct < 1) printf("you.\n");
58841234Sbostic else {
58941234Sbostic if(playerct > 1) printf("any of ");
59041234Sbostic for(i=0; i<playerct; i++)
59141234Sbostic printf("%s%s", players[i], (i<playerct-1)?", ":".\n");
59241234Sbostic printf("Call is: %s -s [playernames]\n", hname);
59341234Sbostic }
59441234Sbostic }
59541234Sbostic return;
59641234Sbostic }
59741234Sbostic
59841234Sbostic if(outflg) outheader();
59941234Sbostic t1 = tt_head;
60041234Sbostic for(rank = 1; t1->points != 0; rank++, t1 = t2) {
60141234Sbostic t2 = t1->tt_next;
60241234Sbostic #ifdef PERS_IS_UID
60341234Sbostic if(!playerct && t1->uid == uid)
60441234Sbostic goto outwithit;
60541234Sbostic else
60641234Sbostic #endif PERS_IS_UID
60741234Sbostic for(i = 0; i < playerct; i++){
60841234Sbostic if(strcmp(players[i], "all") == 0 ||
60941234Sbostic strncmp(t1->name, players[i], NAMSZ) == 0 ||
61041234Sbostic (players[i][0] == '-' &&
61141234Sbostic players[i][1] == t1->plchar &&
61241234Sbostic players[i][2] == 0) ||
61341234Sbostic (digit(players[i][0]) && rank <= atoi(players[i]))){
61441234Sbostic outwithit:
61541234Sbostic if(outflg)
61641234Sbostic (void) outentry(rank, t1, 0);
61741234Sbostic #ifdef nonsense
61841234Sbostic total_score += t1->points;
61941234Sbostic if(totcharct < sizeof(totchars)-1)
62041234Sbostic totchars[totcharct++] = t1->plchar;
62141234Sbostic #endif nonsense
62241234Sbostic break;
62341234Sbostic }
62441234Sbostic }
62541234Sbostic free((char *) t1);
62641234Sbostic }
62741234Sbostic #ifdef nonsense
62841234Sbostic totchars[totcharct] = 0;
62941234Sbostic
63041234Sbostic /* We would like to determine whether he is experienced. However,
63141234Sbostic the information collected here only tells about the scores/roles
63241234Sbostic that got into the topten (top 100?). We should maintain a
63341234Sbostic .hacklog or something in his home directory. */
63441234Sbostic flags.beginner = (total_score < 6000);
63541234Sbostic for(i=0; i<6; i++)
63641234Sbostic if(!index(totchars, "CFKSTWX"[i])) {
63741234Sbostic flags.beginner = 1;
63841234Sbostic if(!pl_character[0]) pl_character[0] = "CFKSTWX"[i];
63941234Sbostic break;
64041234Sbostic }
64141234Sbostic #endif nonsense
64241234Sbostic }
643