Annotation of early-roguelike/rogue3/rip.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * File for the fun ends
! 3: * Death or a total win
! 4: *
! 5: * @(#)rip.c 3.13 (Berkeley) 6/16/81
! 6: *
! 7: * Rogue: Exploring the Dungeons of Doom
! 8: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 9: * All rights reserved.
! 10: *
! 11: * See the file LICENSE.TXT for full copyright and licensing information.
! 12: */
! 13:
! 14: #include <stdlib.h>
! 15: #include <errno.h>
! 16: #include <time.h>
! 17: #include <signal.h>
! 18: #include <ctype.h>
! 19: #include <sys/types.h>
! 20: #include <fcntl.h>
! 21: #include <string.h>
! 22: #include "curses.h"
! 23: #include "machdep.h"
! 24: #include "rogue.h"
! 25:
! 26: static char *rip[] = {
! 27: " __________",
! 28: " / \\",
! 29: " / REST \\",
! 30: " / IN \\",
! 31: " / PEACE \\",
! 32: " / \\",
! 33: " | |",
! 34: " | |",
! 35: " | killed by a |",
! 36: " | |",
! 37: " | 1980 |",
! 38: " *| * * * | *",
! 39: " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
! 40: 0
! 41: };
! 42:
! 43: char *killname();
! 44:
! 45: /*
! 46: * death:
! 47: * Do something really fun when he dies
! 48: */
! 49:
! 50: void
! 51: death(int monst)
! 52: {
! 53: char **dp = rip, *killer;
! 54: struct tm *lt;
! 55: time_t date;
! 56: char buf[80];
! 57:
! 58: /* Don't autosave dead games. It would be a good idea to autosave a
! 59: game that is between death and scoreboard write, but the restore
! 60: code can't handle that case yet. */
! 61: md_onsignal_default();
! 62:
! 63: time(&date);
! 64: lt = localtime(&date);
! 65: clear();
! 66: move(8, 0);
! 67: while (*dp)
! 68: printw("%s\n", *dp++);
! 69: mvaddstr(14, 28-(((int)strlen(whoami)+1)/2), whoami);
! 70: purse -= purse/10;
! 71: sprintf(buf, "%d Au", purse);
! 72: mvaddstr(15, 28-(((int)strlen(buf)+1)/2), buf);
! 73: killer = killname(monst);
! 74: mvaddstr(17, 28-(((int)strlen(killer)+1)/2), killer);
! 75: mvaddstr(16, 33, vowelstr(killer));
! 76: sprintf(prbuf, "%4d", 1900+lt->tm_year);
! 77: mvaddstr(18, 26, prbuf);
! 78: move(LINES-1, 0);
! 79: draw(stdscr);
! 80: writelog(purse, 0, monst);
! 81: score(purse, 0, monst);
! 82: /* Make sure all the output gets through ssh and
! 83: anything else that might be in the way. */
! 84: printf("[Press return to exit]\n");
! 85: fflush(NULL);
! 86: getchar();
! 87: exit(0);
! 88: }
! 89:
! 90: /*
! 91: * score -- figure score and post it.
! 92: */
! 93:
! 94: void
! 95: open_score(void)
! 96: {
! 97: #ifdef SCOREFILE
! 98: char *scorefile = SCOREFILE;
! 99:
! 100: if (scoreboard != NULL) {
! 101: rewind(scoreboard);
! 102: return;
! 103: }
! 104:
! 105: scoreboard = fopen(scorefile, "r+");
! 106:
! 107: if ((scoreboard == NULL) && (errno == ENOENT))
! 108: {
! 109: scoreboard = fopen(scorefile, "w+");
! 110: md_chmod(scorefile,0664);
! 111: }
! 112:
! 113: if (scoreboard == NULL) {
! 114: fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
! 115: fflush(stderr);
! 116: }
! 117: #else
! 118: scoreboard = NULL;
! 119: #endif
! 120: }
! 121:
! 122: /* Same thing, but for the log file. Maybe combine them eventually. */
! 123: void open_log(void)
! 124: {
! 125: #ifdef LOGFILE
! 126: logfi = fopen(LOGFILE, "a");
! 127:
! 128: if (logfi == NULL)
! 129: {
! 130: fprintf(stderr, "Could not open %s for appending: %s\n", LOGFILE, strerror(errno));
! 131: fflush(stderr);
! 132: }
! 133: #else
! 134: logfi = NULL;
! 135: #endif
! 136: return;
! 137: }
! 138:
! 139: /* VARARGS2 */
! 140: void
! 141: score(int amount, int flags, int monst)
! 142: {
! 143: static struct sc_ent {
! 144: int sc_score;
! 145: char sc_name[80];
! 146: int sc_flags;
! 147: int sc_level;
! 148: char sc_login[8];
! 149: int sc_monster;
! 150: } top_ten[10];
! 151: struct sc_ent *scp;
! 152: int i;
! 153: struct sc_ent *sc2;
! 154: FILE *outf;
! 155: char *killer;
! 156: int prflags = 0;
! 157: static char *reason[] = {
! 158: "killed",
! 159: "quit",
! 160: "A total winner",
! 161: };
! 162: char scoreline[100];
! 163: int rogue_ver = 0, scorefile_ver = 0;
! 164:
! 165: /*
! 166: * Open file and read list
! 167: */
! 168:
! 169: if (scoreboard == NULL)
! 170: return;
! 171:
! 172: outf = scoreboard;
! 173:
! 174: for (scp = top_ten; scp <= &top_ten[9]; scp++)
! 175: {
! 176: scp->sc_score = 0;
! 177: for (i = 0; i < 80; i++)
! 178: scp->sc_name[i] = rnd(255);
! 179: scp->sc_flags = RN;
! 180: scp->sc_level = RN;
! 181: scp->sc_monster = RN;
! 182: scp->sc_login[0] = '\0';
! 183: }
! 184:
! 185: signal(SIGINT, SIG_DFL);
! 186: if ((flags != -1) && (flags != 1))
! 187: {
! 188: mvaddstr(LINES-1, 0, "[Press return to continue]");
! 189: draw(stdscr);
! 190: prbuf[0] = 0;
! 191: get_str(prbuf, stdscr);
! 192: endwin();
! 193: }
! 194: if (wizard)
! 195: if (strcmp(prbuf, "names") == 0)
! 196: prflags = 1;
! 197: else if (strcmp(prbuf, "edit") == 0)
! 198: prflags = 2;
! 199:
! 200: md_lockfile(outf);
! 201:
! 202: encread(scoreline, 100, outf);
! 203: (void) sscanf(scoreline, "R%d %d\n", &rogue_ver, &scorefile_ver);
! 204:
! 205: if ((rogue_ver == 36) && (scorefile_ver == 2))
! 206: for(i = 0; i < 10; i++)
! 207: {
! 208: encread(&top_ten[i].sc_name, 80, outf);
! 209: encread(&top_ten[i].sc_login, 8, outf);
! 210: encread(scoreline, 100, outf);
! 211: (void) sscanf(scoreline, " %d %d %d %d \n",
! 212: &top_ten[i].sc_score, &top_ten[i].sc_flags,
! 213: &top_ten[i].sc_level, &top_ten[i].sc_monster);
! 214: }
! 215:
! 216: /*
! 217: * Insert her in list if need be
! 218: */
! 219: if (!waswizard)
! 220: {
! 221: for (scp = top_ten; scp <= &top_ten[9]; scp++)
! 222: if (amount > scp->sc_score)
! 223: break;
! 224: if (scp <= &top_ten[9])
! 225: {
! 226: for (sc2 = &top_ten[9]; sc2 > scp; sc2--)
! 227: *sc2 = *(sc2-1);
! 228: scp->sc_score = amount;
! 229: strcpy(scp->sc_name, whoami);
! 230: scp->sc_flags = flags;
! 231: if (flags == 2)
! 232: scp->sc_level = max_level;
! 233: else
! 234: scp->sc_level = level;
! 235: scp->sc_monster = monst;
! 236: strncpy(scp->sc_login, md_getusername(), 8);
! 237: }
! 238: }
! 239: /*
! 240: * Print the list
! 241: */
! 242: if (flags != -1)
! 243: printf("\n\n\n");
! 244: printf("Top Ten Adventurers:\nRank\tScore\tName\n");
! 245: for (scp = top_ten; scp <= &top_ten[9]; scp++) {
! 246: if (scp->sc_score) {
! 247: printf("%d\t%d\t%s: %s on level %d", scp - top_ten + 1,
! 248: scp->sc_score, scp->sc_name, reason[scp->sc_flags],
! 249: scp->sc_level);
! 250: if (scp->sc_flags == 0) {
! 251: printf(" by a");
! 252: killer = killname(scp->sc_monster);
! 253: if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
! 254: *killer == 'o' || *killer == 'u')
! 255: putchar('n');
! 256: printf(" %s", killer);
! 257: }
! 258: if (prflags == 1)
! 259: {
! 260: printf(" (%s)", scp->sc_login);
! 261: putchar('\n');
! 262: }
! 263: else if (prflags == 2)
! 264: {
! 265: fflush(stdout);
! 266: fgets(prbuf,80,stdin);
! 267: if (prbuf[0] == 'd')
! 268: {
! 269: for (sc2 = scp; sc2 < &top_ten[9]; sc2++)
! 270: *sc2 = *(sc2 + 1);
! 271: top_ten[9].sc_score = 0;
! 272: for (i = 0; i < 80; i++)
! 273: top_ten[9].sc_name[i] = rnd(255);
! 274: top_ten[9].sc_flags = RN;
! 275: top_ten[9].sc_level = RN;
! 276: top_ten[9].sc_monster = RN;
! 277: scp--;
! 278: }
! 279: }
! 280: else
! 281: printf(".\n");
! 282: }
! 283: }
! 284:
! 285: /*
! 286: * Update the list file
! 287: */
! 288:
! 289: rewind(outf);
! 290:
! 291: strcpy(scoreline, "R36 2\n");
! 292: encwrite(scoreline, 100, outf);
! 293:
! 294: for(i = 0; i < 10; i++)
! 295: {
! 296: encwrite(&top_ten[i].sc_name, 80, outf);
! 297: encwrite(&top_ten[i].sc_login, 8, outf);
! 298: sprintf(scoreline, " %d %d %d %d \n",
! 299: top_ten[i].sc_score, top_ten[i].sc_flags,
! 300: top_ten[i].sc_level, top_ten[i].sc_monster);
! 301: encwrite(scoreline, 100, outf);
! 302: }
! 303:
! 304: md_unlockfile(outf);
! 305:
! 306: fclose(outf);
! 307: }
! 308:
! 309: void writelog(int amount, int flags, int monst)
! 310: {
! 311: char logmessage[220], ltemp[80];
! 312: char *killer;
! 313:
! 314: if (waswizard)
! 315: return;
! 316: #ifdef LOGFILE
! 317: sprintf(logmessage, "%ld %d %s %d ", time(NULL), amount, whoami,
! 318: pstats.s_lvl);
! 319: if (flags == 0) /* died */
! 320: {
! 321: strcat(logmessage, "killed by a");
! 322: killer = killname(monst);
! 323: if (*killer == 'a' || *killer == 'e' || *killer == 'i' ||
! 324: *killer == 'o' || *killer == 'u')
! 325: strcat(logmessage, "n ");
! 326: else
! 327: strcat(logmessage, " ");
! 328: strcat(logmessage, killer);
! 329: if (amulet)
! 330: sprintf(ltemp, " on level %d [max %d] with the Amulet\n",
! 331: level, max_level);
! 332: else
! 333: sprintf(ltemp, " on level %d\n", level);
! 334: strcat(logmessage, ltemp);
! 335: }
! 336: else if (flags == 1) /* quit */
! 337: {
! 338: if (amulet)
! 339: sprintf(ltemp, "quit on level %d [max %d] with the Amulet\n",
! 340: level, max_level);
! 341: else
! 342: sprintf(ltemp, "quit on level %d\n", level);
! 343: strcat(logmessage, ltemp);
! 344: }
! 345: else if (flags == 2) /* won */
! 346: {
! 347: sprintf(ltemp, "escaped with the Amulet [deepest level: %d]\n",
! 348: max_level);
! 349: strcat(logmessage, ltemp);
! 350: }
! 351: else
! 352: return;
! 353:
! 354: if (logfi == NULL)
! 355: return;
! 356: /* and write it */
! 357: md_lockfile(logfi);
! 358: fprintf(logfi, "%s", logmessage);
! 359: md_unlockfile(logfi);
! 360: fclose(logfi);
! 361: #endif
! 362: return;
! 363: }
! 364:
! 365: void
! 366: total_winner()
! 367: {
! 368: struct linked_list *item;
! 369: struct object *obj;
! 370: int worth = 0;
! 371: int c;
! 372: int oldpurse;
! 373:
! 374: clear();
! 375: standout();
! 376: addstr(" \n");
! 377: addstr(" @ @ @ @ @ @@@ @ @ \n");
! 378: addstr(" @ @ @@ @@ @ @ @ @ \n");
! 379: addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
! 380: addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
! 381: addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
! 382: addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
! 383: addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
! 384: addstr(" \n");
! 385: addstr(" Congratulations, you have made it to the light of day! \n");
! 386: standend();
! 387: addstr("\nYou have joined the elite ranks of those who have escaped the\n");
! 388: addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
! 389: addstr("a great profit and are admitted to the fighters guild.\n");
! 390: mvaddstr(LINES - 1, 0, "--Press space to continue--");
! 391: refresh();
! 392: wait_for(stdscr, ' ');
! 393: clear();
! 394: mvaddstr(0, 0, " Worth Item");
! 395: oldpurse = purse;
! 396: for (c = 'a', item = pack; item != NULL; c++, item = next(item))
! 397: {
! 398: obj = (struct object *) ldata(item);
! 399: switch (obj->o_type)
! 400: {
! 401: case FOOD:
! 402: worth = 2 * obj->o_count;
! 403: when WEAPON:
! 404: switch (obj->o_which)
! 405: {
! 406: case MACE: worth = 8;
! 407: when SWORD: worth = 15;
! 408: when BOW: worth = 75;
! 409: when ARROW: worth = 1;
! 410: when DAGGER: worth = 2;
! 411: when ROCK: worth = 1;
! 412: when TWOSWORD: worth = 30;
! 413: when SLING: worth = 1;
! 414: when DART: worth = 1;
! 415: when CROSSBOW: worth = 15;
! 416: when BOLT: worth = 1;
! 417: when SPEAR: worth = 2;
! 418: otherwise: worth = 0;
! 419: }
! 420: worth *= (1 + (10 * obj->o_hplus + 10 * obj->o_dplus));
! 421: worth *= obj->o_count;
! 422: obj->o_flags |= ISKNOW;
! 423: when ARMOR:
! 424: switch (obj->o_which)
! 425: {
! 426: case LEATHER: worth = 5;
! 427: when RING_MAIL: worth = 30;
! 428: when STUDDED_LEATHER: worth = 15;
! 429: when SCALE_MAIL: worth = 3;
! 430: when CHAIN_MAIL: worth = 75;
! 431: when SPLINT_MAIL: worth = 80;
! 432: when BANDED_MAIL: worth = 90;
! 433: when PLATE_MAIL: worth = 400;
! 434: otherwise: worth = 0;
! 435: }
! 436: if (obj->o_which >= MAXARMORS)
! 437: break;
! 438: worth *= (1 + (10 * (a_class[obj->o_which] - obj->o_ac)));
! 439: obj->o_flags |= ISKNOW;
! 440: when SCROLL:
! 441: s_know[obj->o_which] = TRUE;
! 442: worth = s_magic[obj->o_which].mi_worth;
! 443: worth *= obj->o_count;
! 444: when POTION:
! 445: p_know[obj->o_which] = TRUE;
! 446: worth = p_magic[obj->o_which].mi_worth;
! 447: worth *= obj->o_count;
! 448: when RING:
! 449: obj->o_flags |= ISKNOW;
! 450: r_know[obj->o_which] = TRUE;
! 451: worth = r_magic[obj->o_which].mi_worth;
! 452: if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
! 453: obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
! 454: if (obj->o_ac > 0)
! 455: worth += obj->o_ac * 20;
! 456: else
! 457: worth = 50;
! 458: when STICK:
! 459: obj->o_flags |= ISKNOW;
! 460: ws_know[obj->o_which] = TRUE;
! 461: worth = ws_magic[obj->o_which].mi_worth;
! 462: worth += 20 * obj->o_charges;
! 463: when AMULET:
! 464: worth = 1000;
! 465: }
! 466: mvprintw(c - 'a' + 1, 0, "%c) %5d %s", c, worth, inv_name(obj, FALSE));
! 467: purse += worth;
! 468: }
! 469: mvprintw(c - 'a' + 1, 0," %5d Gold Peices ", oldpurse);
! 470: refresh();
! 471: writelog(purse, 2, 0);
! 472: score(purse, 2, 0);
! 473: printf("[Press return to exit]\n");
! 474: fflush(NULL);
! 475: getchar();
! 476: exit(0);
! 477: }
! 478:
! 479: char *
! 480: killname(int monst)
! 481: {
! 482: if (isupper(monst))
! 483: return monsters[monst-'A'].m_name;
! 484: else
! 485: switch (monst)
! 486: {
! 487: case 'a':
! 488: return "arrow";
! 489: case 'd':
! 490: return "dart";
! 491: case 'b':
! 492: return "bolt";
! 493: }
! 494: return("");
! 495: }
CVSweb