[BACK]Return to rip.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / xrogue

Annotation of early-roguelike/xrogue/rip.c, Revision 1.1.1.1

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

CVSweb