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