Annotation of early-roguelike/arogue5/rip.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * File for the fun ends
3: * Death or a total win
4: *
5: * Advanced Rogue
6: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
7: * All rights reserved.
8: *
9: * Based on "Rogue: Exploring the Dungeons of Doom"
10: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
11: * All rights reserved.
12: *
13: * See the file LICENSE.TXT for full copyright and licensing information.
14: */
15:
16: /* Print flags for scoring */
17: #define REALLIFE 1 /* Print out machine and logname */
18: #define EDITSCORE 2 /* Edit the current score file */
19: #define ADDSCORE 3 /* Add a new score */
20:
21: #include <fcntl.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include "curses.h"
26: #include <time.h>
27: #include <signal.h>
28: #include <ctype.h>
29: #include <sys/types.h>
30: #include "network.h"
31: #include "rogue.h"
32: #include "mach_dep.h"
33:
34: /*
35: * If you change this structure, change the compatibility routines
36: * scoreout() and scorein() to reflect the change. Also update SCORELEN.
37: */
38:
39: struct sc_ent {
40: unsigned long sc_score;
41: char sc_name[LINELEN];
42: char sc_system[SYSLEN];
43: char sc_login[LOGLEN];
44: short sc_flgs;
45: short sc_level;
46: short sc_ctype;
47: short sc_monster;
48: short sc_quest;
49: };
50:
51: #define SCORELEN \
52: (sizeof(unsigned long) + LINELEN + SYSLEN + LOGLEN + 5*sizeof(short))
53:
54: static char *rip[] = {
55: " __________",
56: " / \\",
57: " / REST \\",
58: " / IN \\",
59: " / PEACE \\",
60: " / \\",
61: " | |",
62: " | |",
63: " | killed by |",
64: " | |",
65: " | 1984 |",
66: " *| * * * | *",
67: " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
68: 0
69: };
70:
71: char *killname(short monst);
72: void scorein(struct sc_ent scores[], FILE *inf);
73: void scoreout(struct sc_ent scores[], FILE *outf);
74: void showpack(char *howso);
75: int update(struct sc_ent top_ten[], unsigned long amount, short quest,
76: char *whoami, short flags, short level, short monst, short ctype,
77: char *system, char *login);
78:
79:
80: void
81: byebye(int sig)
82: {
83: NOOP(sig);
84: if (!isendwin()) {
85: clear();
86: endwin();
87: }
88: printf("\n");
89: exit(0);
90: }
91:
92:
93: /*
94: * death:
95: * Do something really fun when he dies
96: */
97:
98: void
99: death(short monst)
100: {
101: register char **dp = rip, *killer;
102: register struct tm *lt;
103: time_t date;
104: char buf[80];
105: struct tm *localtime();
106:
107: time(&date);
108: lt = localtime(&date);
109: clear();
110: move(8, 0);
111: while (*dp)
112: printw("%s\n", *dp++);
113: mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami);
114: sprintf(buf, "%lu Points", pstats.s_exp );
115: mvaddstr(15, 28-((strlen(buf)+1)/2), buf);
116: killer = killname(monst);
117: mvaddstr(17, 28-((strlen(killer)+1)/2), killer);
118: mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf));
119: move(LINES-1, 0);
120: refresh();
121: writelog(pstats.s_exp, KILLED, monst);
122: score(pstats.s_exp, KILLED, monst);
123: exit(0);
124: }
125:
126: char *
127: killname(short monst)
128: {
129: static char mons_name[LINELEN];
130: int i;
131:
132: if (monst > NUMMONST) return("a strange monster");
133:
134: if (monst >= 0) {
135: switch (monsters[monst].m_name[0]) {
136: case 'a':
137: case 'e':
138: case 'i':
139: case 'o':
140: case 'u':
141: sprintf(mons_name, "an %s", monsters[monst].m_name);
142: break;
143: default:
144: sprintf(mons_name, "a %s", monsters[monst].m_name);
145: }
146: return(mons_name);
147: }
148: for (i = 0; i< DEATHNUM; i++) {
149: if (deaths[i].reason == monst)
150: break;
151: }
152: if (i >= DEATHNUM)
153: return ("strange death");
154: return (deaths[i].name);
155: }
156:
157:
158: /*
159: * score -- figure score and post it.
160: */
161:
162: /* VARARGS2 */
163: void
164: score(unsigned long amount, int flags, short monst)
165: {
166: static struct sc_ent top_ten[NUMSCORE];
167: register struct sc_ent *scp;
168: register int i;
169: register struct sc_ent *sc2;
170: register char *killer;
171: register int prflags = 0;
172: short upquest = 0, wintype = 0, uplevel = 0, uptype = 0; /* For network updating */
173: char upsystem[SYSLEN], uplogin[LOGLEN];
174: char *thissys; /* Holds the name of this system */
175: char *compatstr=NULL; /* Holds scores for writing compatible score files */
176: #define REASONLEN 3
177: static char *reason[] = {
178: "killed",
179: "quit",
180: "A total winner",
181: "somehow left",
182: };
183: char *packend;
184: memset(top_ten,0,sizeof(top_ten));
185: signal(SIGINT, byebye);
186: if (flags != WINNER && flags != SCOREIT && flags != UPDATE) {
187: if (flags == CHICKEN)
188: packend = "when you quit";
189: else
190: packend = "at your untimely demise";
191: mvaddstr(LINES - 1, 0, retstr);
192: refresh();
193: wgetnstr(cw,prbuf,80);
194: showpack(packend);
195: }
196: purse = 0; /* Steal all the gold */
197:
198: /*
199: * Open file and read list
200: */
201:
202: if (scoreboard == NULL)
203: {
204: printf("\nCannot open score_file.\n");
205: return;
206: }
207:
208: /* Get this system's name */
209: thissys = md_gethostname();
210:
211: for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++)
212: {
213: scp->sc_score = 0L;
214: for (i = 0; i < 80; i++)
215: scp->sc_name[i] = rnd(255);
216: scp->sc_quest= RN;
217: scp->sc_flgs = RN;
218: scp->sc_level = RN;
219: scp->sc_monster = RN;
220: scp->sc_ctype = 0;
221: strncpy(scp->sc_system, thissys, SYSLEN);
222: scp->sc_login[0] = '\0';
223: }
224:
225: /*
226: * If this is a SCOREIT optin (rogue -s), don't call byebye. The
227: * endwin() call in byebye() will result in a core dump.
228: */
229: if (flags == SCOREIT) signal(SIGINT, SIG_DFL);
230: else signal(SIGINT, byebye);
231:
232: if (flags != SCOREIT && flags != UPDATE)
233: {
234: mvaddstr(LINES - 1, 0, retstr);
235: refresh();
236: fflush(stdout);
237: wgetnstr(stdscr,prbuf,80);
238: }
239:
240: /* Check for special options */
241: if (strcmp(prbuf, "names") == 0)
242: prflags = REALLIFE;
243: #ifdef WIZARD
244: else if (wizard) {
245: if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE;
246: else if (strcmp(prbuf, "add") == 0) {
247: prflags = ADDSCORE;
248: waswizard = FALSE; /* We want the new score recorded */
249: }
250: }
251: #endif
252:
253: /* Read the score and convert it to a compatible format */
254: scorein(top_ten, scoreboard); /* Convert it */
255:
256: /* Get some values if this is an update */
257: if (flags == UPDATE) {
258: int errcheck, errors = 0;
259:
260: upquest = (short) netread(&errcheck, sizeof(short), stdin);
261: if (errcheck) errors++;
262:
263: if (fread(whoami, 1, LINELEN, stdin) != LINELEN) errors++;
264:
265: wintype = (short) netread(&errcheck, sizeof(short), stdin);
266: if (errcheck) errors++;
267:
268: uplevel = (short) netread(&errcheck, sizeof(short), stdin);
269: if (errcheck) errors++;
270:
271: uptype = (short) netread(&errcheck, sizeof(short), stdin);
272: if (errcheck) errors++;
273:
274: if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN)
275: errors++;
276: if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN)
277: errors++;
278:
279: if (errors) {
280: fclose(scoreboard);
281: free(compatstr);
282: return;
283: }
284: }
285:
286: /*
287: * Insert player in list if need be
288: */
289: if (!waswizard) {
290: char *login = NULL;
291:
292: if (flags != UPDATE) {
293: login = md_getusername();
294: }
295:
296: if (flags == UPDATE)
297: (void) update(top_ten, amount, upquest, whoami, wintype,
298: uplevel, monst, uptype, upsystem, uplogin);
299: else {
300: #ifdef WIZARD
301: if (prflags == ADDSCORE) { /* Overlay characteristic by new ones */
302: char buffer[80];
303: int atoi();
304:
305: clear();
306: mvaddstr(1, 0, "Score: ");
307: mvaddstr(2, 0, "Quest (number): ");
308: mvaddstr(3, 0, "Name: ");
309: mvaddstr(4, 0, "System: ");
310: mvaddstr(5, 0, "Login: ");
311: mvaddstr(6, 0, "Level: ");
312: mvaddstr(7, 0, "Char type: ");
313: mvaddstr(8, 0, "Result: ");
314:
315: /* Get the score */
316: move(1, 7);
317: get_str(buffer, stdscr);
318: amount = atol(buffer);
319:
320: /* Get the character's quest -- must be a number */
321: move(2, 16);
322: get_str(buffer, stdscr);
323: quest_item = atoi(buffer);
324:
325: /* Get the character's name */
326: move(3, 6);
327: get_str(buffer, stdscr);
328: strncpy(whoami, buffer, LINELEN);
329:
330: /* Get the system */
331: move(4, 8);
332: get_str(buffer, stdscr);
333: strncpy(thissys, buffer, SYSLEN);
334:
335: /* Get the login */
336: move(5, 7);
337: get_str(buffer, stdscr);
338: strncpy(login, buffer, LOGLEN);
339:
340: /* Get the level */
341: move(6, 7);
342: get_str(buffer, stdscr);
343: level = max_level = (short) atoi(buffer);
344:
345: /* Get the character type */
346: move(7, 11);
347: get_str(buffer, stdscr);
348: switch (buffer[0]) {
349: case 'F':
350: case 'f':
351: default:
352: player.t_ctype = C_FIGHTER;
353: break;
354:
355: case 'C':
356: case 'c':
357: player.t_ctype = C_CLERIC;
358: break;
359:
360: case 'M':
361: case 'm':
362: player.t_ctype = C_MAGICIAN;
363: break;
364:
365: case 'T':
366: case 't':
367: player.t_ctype = C_THIEF;
368: break;
369: }
370:
371: /* Get the win type */
372: move(8, 8);
373: get_str(buffer, stdscr);
374: switch (buffer[0]) {
375: case 'W':
376: case 'w':
377: case 'T':
378: case 't':
379: flags = WINNER;
380: break;
381:
382: case 'Q':
383: case 'q':
384: flags = CHICKEN;
385: break;
386:
387: case 'k':
388: case 'K':
389: default:
390: flags = KILLED;
391: break;
392: }
393:
394: /* Get the monster if player was killed */
395: if (flags == KILLED) {
396: mvaddstr(9, 0, "Death type: ");
397: get_str(buffer, stdscr);
398: if (buffer[0] == 'M' || buffer[0] == 'm')
399: monst = makemonster(FALSE);
400: else monst = getdeath();
401: }
402: }
403: #endif
404:
405: if (update(top_ten, amount, (short) quest_item, whoami, flags,
406: (flags == WINNER) ? (short) max_level : (short) level,
407: monst, player.t_ctype, thissys, login)
408: #ifdef NUMNET
409: && fork() == 0 /* Spin off network process */
410: #endif
411: ) {
412: #ifdef NUMNET
413: /* Send this update to the other systems in the network */
414: int i, j;
415: char cmd[256]; /* Command for remote execution */
416: FILE *rmf, *popen(); /* For input to remote command */
417:
418: for (i=0; i<NUMNET; i++)
419: if (Network[i].system[0] != '!' &&
420: strcmp(Network[i].system, thissys)) {
421: sprintf(cmd,
422: "usend -s -d%s -uNoLogin -!'%s -u' - 2>/dev/null",
423: Network[i].system, Network[i].rogue);
424:
425: /* Execute the command */
426: if ((rmf=popen(cmd, "w")) != NULL) {
427: unsigned long temp; /* Temporary value */
428:
429: /* Write out the parameters */
430: (void) netwrite((unsigned long) amount,
431: sizeof(unsigned long), rmf);
432:
433: (void) netwrite((unsigned long) monst,
434: sizeof(short), rmf);
435:
436: (void) netwrite((unsigned long) quest_item,
437: sizeof(short), rmf);
438:
439: (void) fwrite(whoami, 1, strlen(whoami), rmf);
440: for (j=strlen(whoami); j<LINELEN; j++)
441: putc('\0', rmf);
442:
443: (void) netwrite((unsigned long) flags,
444: sizeof(short), rmf);
445:
446: temp = (unsigned long)
447: (flags==WINNER ? max_level : level);
448: (void) netwrite(temp, sizeof(short), rmf);
449:
450: (void) netwrite((unsigned long) player.t_ctype,
451: sizeof(short), rmf);
452:
453: (void) fwrite(thissys, 1,
454: strlen(thissys), rmf);
455: for (j=strlen(thissys); j<SYSLEN; j++)
456: putc('\0', rmf);
457:
458: (void) fwrite(login, 1, strlen(login), rmf);
459: for (j=strlen(login); j<LOGLEN; j++)
460: putc('\0', rmf);
461:
462: /* Close off the command */
463: (void) pclose(rmf);
464: }
465: }
466: _exit(0); /* Exit network process */
467: #endif
468: }
469: }
470: }
471:
472: fseek(scoreboard, 0L, 0);
473: /*
474: * Update the list file
475: */
476: scoreout(top_ten, scoreboard);
477: fclose(scoreboard);
478:
479: /*
480: * SCOREIT -- rogue -s option. Never started curses if this option.
481: * UPDATE -- network scoring update. Never started curses if this option.
482: * EDITSCORE -- want to delete or change a score.
483: */
484: /* if (flags != SCOREIT && flags != UPDATE && prflags != EDITSCORE)
485: endwin(); */
486:
487: if (flags != UPDATE) {
488: if (flags != SCOREIT) {
489: clear();
490: refresh();
491: endwin();
492: }
493: /*
494: * Print the list
495: */
496: printf("\nTop %d Adventurers:\nRank Score\tName\n",
497: NUMSCORE);
498:
499: for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++) {
500: char *class;
501:
502: if (scp->sc_score != 0) {
503: switch (scp->sc_ctype) {
504: case C_FIGHTER: class = "fighter";
505: when C_MAGICIAN: class = "magician";
506: when C_CLERIC: class = "cleric";
507: when C_THIEF: class = "thief";
508: otherwise: class = "unknown";
509: }
510:
511: /* Make sure we have an in-bound reason */
512: if (scp->sc_flgs > REASONLEN) scp->sc_flgs = REASONLEN;
513:
514: printf("%3d %10lu\t%s (%s)", scp - top_ten + 1,
515: scp->sc_score, scp->sc_name, class);
516:
517: if (prflags == REALLIFE) printf(" [in real life %.*s!%.*s]",
518: SYSLEN, scp->sc_system, LOGLEN, scp->sc_login);
519: printf(":\n\t\t%s on level %d", reason[scp->sc_flgs],
520: scp->sc_level);
521:
522: switch (scp->sc_flgs) {
523: case KILLED:
524: printf(" by");
525: killer = killname(scp->sc_monster);
526: printf(" %s", killer);
527: break;
528:
529: case WINNER:
530: printf(" with the %s",
531: rel_magic[scp->sc_quest].mi_name);
532: break;
533: }
534:
535: if (prflags == EDITSCORE)
536: {
537: fflush(stdout);
538: fgets(prbuf,80,stdin);
539: printf("\n");
540: if (prbuf[0] == 'd') {
541: for (sc2 = scp; sc2 < &top_ten[NUMSCORE-1]; sc2++)
542: *sc2 = *(sc2 + 1);
543: top_ten[NUMSCORE-1].sc_score = 0;
544: for (i = 0; i < 80; i++)
545: top_ten[NUMSCORE-1].sc_name[i] = rnd(255);
546: top_ten[NUMSCORE-1].sc_flgs = RN;
547: top_ten[NUMSCORE-1].sc_level = RN;
548: top_ten[NUMSCORE-1].sc_monster = RN;
549: scp--;
550: }
551: else if (prbuf[0] == 'e') {
552: printf("Death type: ");
553: fgets(prbuf,80,stdin);
554: if (prbuf[0] == 'M' || prbuf[0] == 'm')
555: scp->sc_monster = makemonster(FALSE);
556: else scp->sc_monster = getdeath();
557: clear();
558: refresh();
559: }
560: }
561: else printf("\n");
562: }
563: }
564: /* if (prflags == EDITSCORE) endwin(); */ /* End editing windowing */
565: }
566:
567: if ((flags != SCOREIT) && (flags != UPDATE)) {
568: printf("\n[Press return to exit]");
569: fflush(stdout);
570: fgets(prbuf,80,stdin);
571: }
572: }
573:
574: void writelog(unsigned long amount, int flags, short monst) {
575: #ifdef LOGFILE
576: char fate[100];
577: char *class;
578: struct linked_list *item;
579: struct object *obj;
580: char had_quest = '0';
581:
582: if (waswizard)
583: return;
584: if (logfile == NULL)
585: return;
586: switch (player.t_ctype) {
587: case C_FIGHTER: class = "Fighter";
588: when C_MAGICIAN: class = "Magician";
589: when C_CLERIC: class = "Cleric";
590: when C_THIEF: class = "Thief";
591: otherwise: class = "Unknown";
592: }
593: for (item = pack; item != NULL; item = next(item)) {
594: obj = OBJPTR(item);
595: if (obj->o_type == RELIC && obj->o_which == quest_item)
596: had_quest = '1';
597: }
598: if (flags == KILLED) {
599: sprintf(fate, "killed by %s", killname(monst));
600: }
601: else if (flags == CHICKEN) {
602: sprintf(fate, "quit");
603: }
604: else if (flags == WINNER) {
605: sprintf(fate, "escaped");
606: }
607: else
608: return;
609:
610: fprintf(logfile, "%ld %ld %s %d %s %d %d %d %c %s\n", time(NULL), amount,
611: whoami, pstats.s_lvl, class, level, max_level, quest_item, had_quest,
612: fate);
613: fclose(logfile);
614: #endif
615: return;
616: }
617:
618: /*
619: * scorein:
620: * Convert a character string that has been translated from a
621: * score file by scoreout() back to a score file structure.
622: */
623: void
624: scorein(struct sc_ent scores[], FILE *inf)
625: {
626: int i;
627: char scoreline[100];
628:
629: for(i = 0; i < NUMSCORE; i++)
630: {
631: encread((char *) &scores[i].sc_name, LINELEN, inf);
632: encread((char *) &scores[i].sc_system, SYSLEN, inf);
633: encread((char *) &scores[i].sc_login, LINELEN, inf);
634: encread((char *) scoreline, 100, inf);
635: sscanf(scoreline, " %lu %d %d %d %d %d \n",
636: &scores[i].sc_score, &scores[i].sc_flgs,
637: &scores[i].sc_level, &scores[i].sc_ctype,
638: &scores[i].sc_monster, &scores[i].sc_quest);
639: }
640: }
641:
642: /*
643: * scoreout:
644: * Convert a score file structure to a character string. We do
645: * this for compatibility sake since some machines write out fields in
646: * different orders.
647: */
648: void
649: scoreout(struct sc_ent scores[], FILE *outf)
650: {
651: int i;
652: char scoreline[100];
653:
654: for(i = 0; i < NUMSCORE; i++) {
655: memset(scoreline,0,100);
656: encwrite((char *) scores[i].sc_name, LINELEN, outf);
657: encwrite((char *) scores[i].sc_system, SYSLEN, outf);
658: encwrite((char *) scores[i].sc_login, LINELEN, outf);
659: sprintf(scoreline, " %lu %d %d %d %d %d \n",
660: scores[i].sc_score, scores[i].sc_flgs,
661: scores[i].sc_level, scores[i].sc_ctype,
662: scores[i].sc_monster,scores[i].sc_quest);
663: encwrite((char *) scoreline, 100, outf);
664: }
665: }
666:
667: /*
668: * showpack:
669: * Display the contents of the hero's pack
670: */
671: void
672: showpack(char *howso)
673: {
674: reg char *iname;
675: reg int cnt, packnum;
676: reg struct linked_list *item;
677: reg struct object *obj;
678:
679: idenpack();
680: cnt = 1;
681: clear();
682: mvprintw(0, 0, "Contents of your pack %s:\n",howso);
683: packnum = 'a';
684: for (item = pack; item != NULL; item = next(item)) {
685: obj = OBJPTR(item);
686: iname = inv_name(obj, FALSE);
687: mvprintw(cnt, 0, "%c) %s\n",packnum++,iname);
688: if (++cnt >= LINES - 2 &&
689: next(item) != NULL) {
690: cnt = 1;
691: mvaddstr(LINES - 1, 0, morestr);
692: refresh();
693: wait_for(stdscr,' ');
694: clear();
695: }
696: }
697: mvprintw(cnt + 1,0,"--- %d Gold Pieces ---",purse);
698: refresh();
699: }
700:
701: void
702: total_winner(void)
703: {
704: register struct linked_list *item;
705: register struct object *obj;
706: register int worth;
707: register char c;
708: register int oldpurse;
709:
710: clear();
711: standout();
712: addstr(" \n");
713: addstr(" @ @ @ @ @ @@@ @ @ \n");
714: addstr(" @ @ @@ @@ @ @ @ @ \n");
715: addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
716: addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
717: addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
718: addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
719: addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
720: addstr(" \n");
721: addstr(" Congratulations, you have made it to the light of day! \n");
722: standend();
723: addstr("\nYou have joined the elite ranks of those who have escaped the\n");
724: addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
725: addstr("a great profit and are appointed leader of a ");
726: switch (player.t_ctype) {
727: case C_MAGICIAN:addstr("magic user's guild.\n");
728: when C_FIGHTER: addstr("fighters guild.\n");
729: when C_CLERIC: addstr("monastery.\n");
730: when C_THIEF: addstr("thief's guild.\n");
731: otherwise: addstr("tavern.\n");
732: }
733: mvaddstr(LINES - 1, 0, spacemsg);
734: refresh();
735: wait_for(stdscr,' ');
736: clear();
737: mvaddstr(0, 0, " Worth Item");
738: oldpurse = purse;
739: for (c = 'a', item = pack; item != NULL; c++, item = next(item))
740: {
741: obj = OBJPTR(item);
742: worth = get_worth(obj);
743: if (obj->o_group == 0)
744: worth *= obj->o_count;
745: whatis(item);
746: mvprintw(c - 'a' + 1, 0, "%c) %6d %s", c, worth, inv_name(obj, FALSE));
747: purse += worth;
748: }
749: mvprintw(c - 'a' + 1, 0," %5d Gold Pieces ", oldpurse);
750: refresh();
751: writelog(pstats.s_exp + (long) purse, WINNER, '\0');
752: score(pstats.s_exp + (long) purse, WINNER, '\0');
753: exit(0);
754: }
755:
756: int
757: update(struct sc_ent top_ten[], unsigned long amount, short quest,
758: char *whoami, short flags, short level, short monst, short ctype,
759: char *system, char *login)
760: {
761: register struct sc_ent *scp, *sc2;
762: int retval=0; /* 1 if a change, 0 otherwise */
763:
764: for (scp = top_ten; scp < &top_ten[NUMSCORE]; scp++) {
765: if (amount >= scp->sc_score)
766: break;
767:
768: #ifdef LIMITSCORE /* Limits player to one entry per class per uid */
769: /* If this good score is the same class and uid, then forget it */
770: if (strncmp(scp->sc_login, login, LOGLEN) == 0 &&
771: scp->sc_ctype == ctype &&
772: strncmp(scp->sc_system, system, SYSLEN) == 0) return(0);
773: #endif
774: }
775:
776: if (scp < &top_ten[NUMSCORE])
777: {
778: retval = 1;
779:
780: #ifdef LIMITSCORE /* Limits player to one entry per class per uid */
781: /* If a lower scores exists for the same login and class, delete it */
782: for (sc2 = scp ;sc2 < &top_ten[NUMSCORE]; sc2++) {
783: if (sc2->sc_score == 0L) break; /* End of useful scores */
784:
785: if (strncmp(sc2->sc_login, login, LOGLEN) == 0 &&
786: sc2->sc_ctype == ctype &&
787: strncmp(sc2->sc_system, system, SYSLEN) == 0) {
788: /* We want to delete this entry */
789: while (sc2 < &top_ten[NUMSCORE-1]) {
790: *sc2 = *(sc2+1);
791: sc2++;
792: }
793: sc2->sc_score = 0L;
794: }
795: }
796: #endif
797:
798: for (sc2 = &top_ten[NUMSCORE-1]; sc2 > scp; sc2--)
799: *sc2 = *(sc2-1);
800: scp->sc_score = amount;
801: scp->sc_quest = quest;
802: strncpy(scp->sc_name, whoami, LINELEN);
803: scp->sc_flgs = flags;
804: scp->sc_level = level;
805: scp->sc_monster = monst;
806: scp->sc_ctype = ctype;
807: strncpy(scp->sc_system, system, SYSLEN);
808: strncpy(scp->sc_login, login, LOGLEN);
809: }
810:
811: return(retval);
812: }
CVSweb