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