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