Annotation of early-roguelike/urogue/rip.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: rip.c - File for the fun ends Death or a total win
! 3:
! 4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
! 5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
! 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: #include <string.h>
! 20: #include <stdlib.h>
! 21: #include <ctype.h>
! 22: #include <time.h>
! 23: #include "rogue.h"
! 24:
! 25: static struct sc_ent
! 26: {
! 27: int sc_lvl;
! 28: long sc_score;
! 29: char sc_name[76];
! 30: long sc_gold;
! 31: int sc_flags;
! 32: int sc_level;
! 33: int sc_artifacts;
! 34: int sc_monster;
! 35: } top_ten[10];
! 36:
! 37:
! 38: static const char *rip[] =
! 39: {
! 40: " __________",
! 41: " / \\",
! 42: " / REST \\",
! 43: " / IN \\",
! 44: " / PEACE \\",
! 45: " / \\",
! 46: " | |",
! 47: " | |",
! 48: " | killed by |",
! 49: " | |",
! 50: " | 1993 |",
! 51: " *| * * * | *",
! 52: " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
! 53: 0
! 54: };
! 55:
! 56: void writelog(long amount, int lvl, int flags, int monst);
! 57:
! 58: /*
! 59: death()
! 60: Do something really fun when he dies
! 61: */
! 62:
! 63: void
! 64: death(int monst)
! 65: {
! 66: char **dp = (char **) rip, *killer;
! 67: struct tm *lt;
! 68: time_t date;
! 69: char buf[80];
! 70: int c;
! 71:
! 72: if (is_wearing(R_RESURRECT) || rnd(wizard ? 3 : 67) == 0)
! 73: {
! 74: int die = TRUE;
! 75:
! 76: if (resurrect-- == 0)
! 77: msg("You've run out of lives.");
! 78: else if (!save_resurrect(ring_value(R_RESURRECT)))
! 79: msg("Your attempt to return from the grave fails.");
! 80: else
! 81: {
! 82: struct linked_list *item;
! 83: struct linked_list *next_item;
! 84: struct object *obj;
! 85: int rm, flags;
! 86: coord pos;
! 87:
! 88: die = FALSE;
! 89: msg("You feel a sudden warmth and then nothingness.");
! 90: teleport();
! 91:
! 92: if (ring_value(R_RESURRECT) > 1 && rnd(10))
! 93: {
! 94: pstats.s_hpt = 2 * pstats.s_const;
! 95: pstats.s_const = max(pstats.s_const - 1, 3);
! 96: }
! 97: else
! 98: {
! 99: for (item = pack; item != NULL; item = next_item)
! 100: {
! 101: obj = OBJPTR(item);
! 102:
! 103: if (obj->o_flags & ISOWNED || obj->o_flags & ISPROT)
! 104: {
! 105: next_item = next(item);
! 106: continue;
! 107: }
! 108:
! 109: flags = obj->o_flags;
! 110: obj->o_flags &= ~ISCURSED;
! 111: dropcheck(obj);
! 112: obj->o_flags = flags;
! 113: next_item = next(item);
! 114: rem_pack(obj);
! 115:
! 116: if (obj->o_type == ARTIFACT)
! 117: has_artifact &= ~(1 << obj->o_which);
! 118:
! 119: do
! 120: {
! 121: rm = rnd_room();
! 122: rnd_pos(&rooms[rm], &pos);
! 123: }
! 124: while(winat(pos.y, pos.x) != FLOOR);
! 125:
! 126: obj->o_pos = pos;
! 127: add_obj(item, obj->o_pos.y, obj->o_pos.x);
! 128: }
! 129:
! 130: pstats.s_hpt = pstats.s_const;
! 131: pstats.s_const = max(pstats.s_const - roll(2, 2), 3);
! 132: }
! 133:
! 134: chg_str(roll(1, 4), TRUE, FALSE);
! 135: pstats.s_lvl = max(pstats.s_lvl, 1);
! 136: no_command += 2 + rnd(4);
! 137:
! 138: if (on(player, ISHUH))
! 139: lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION);
! 140: else
! 141: light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER);
! 142:
! 143: turn_on(player, ISHUH);
! 144: light(&hero);
! 145: }
! 146:
! 147: if (die)
! 148: {
! 149: wmove(cw, mpos, 0);
! 150: waddstr(cw, morestr);
! 151: wrefresh(cw);
! 152: wait_for(' ');
! 153: }
! 154: else
! 155: return;
! 156: }
! 157:
! 158: time(&date);
! 159: lt = localtime(&date);
! 160: clear();
! 161: wclear(cw);
! 162: move(8, 0);
! 163:
! 164: while (*dp)
! 165: printw("%s\n", *dp++);
! 166:
! 167: mvaddstr(14, 28 - ((int)(strlen(whoami) + 1) / 2), whoami);
! 168: sprintf(buf, "%d+%ld Points", pstats.s_lvl, pstats.s_exp);
! 169: mvaddstr(15, 28 - ((int)(strlen(buf) + 1) / 2), buf);
! 170: killer = killname(monst,buf);
! 171: mvaddstr(17, 28 - ((int)(strlen(killer) + 1) / 2), killer);
! 172: mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf));
! 173: move(LINES - 1, 0);
! 174:
! 175: mvaddstr(LINES - 1, 0, retstr);
! 176:
! 177: while ((c = readcharw(stdscr)) != '\n' && c != '\r')
! 178: continue;
! 179: idenpack();
! 180: wrefresh(cw);
! 181: refresh();
! 182:
! 183: score(pstats.s_exp, pstats.s_lvl, KILLED, monst);
! 184: byebye();
! 185: }
! 186:
! 187: /*
! 188: score()
! 189: figure score and post it.
! 190: */
! 191:
! 192: void
! 193: score(long amount, int lvl, int flags, int monst) /*ARGSUSED*/
! 194: {
! 195: struct sc_ent *scp=NULL, *sc2=NULL;
! 196: int i;
! 197: char *killer;
! 198: char buf[1024];
! 199:
! 200: static const char *reason[] =
! 201: {
! 202: "killed",
! 203: "quit",
! 204: "a winner",
! 205: "a total winner"
! 206: };
! 207:
! 208: char *packend;
! 209:
! 210: if (flags != SCOREIT)
! 211: writelog(amount, lvl, flags, monst);
! 212:
! 213: if (flags != WINNER && flags != TOTAL && flags != SCOREIT)
! 214: {
! 215: if (flags == CHICKEN)
! 216: packend = "when you quit";
! 217: else
! 218: packend = "at your untimely demise";
! 219:
! 220: noecho();
! 221: nl();
! 222: refresh();
! 223: showpack(packend);
! 224: }
! 225:
! 226: /* Open file and read list */
! 227:
! 228: if (fd_score == NULL)
! 229: {
! 230: printf("No score file opened\n");
! 231: return;
! 232: }
! 233:
! 234: for (scp = top_ten; scp < &top_ten[10]; scp++)
! 235: {
! 236: scp->sc_lvl = 0L;
! 237: scp->sc_score = 0L;
! 238:
! 239: for (i = 0; i < 76; i++)
! 240: scp->sc_name[i] = ucrnd(255);
! 241:
! 242: scp->sc_gold = 0L;
! 243: scp->sc_flags = rnd(10);
! 244: scp->sc_level = rnd(10);
! 245: scp->sc_monster = srnd(10);
! 246: scp->sc_artifacts = 0;
! 247: }
! 248:
! 249: if (flags != SCOREIT)
! 250: {
! 251: mvaddstr(LINES - 1, 0, retstr);
! 252: refresh();
! 253: fflush(stdout);
! 254: wait_for('\n');
! 255: }
! 256:
! 257: fseek(fd_score, 0L, SEEK_SET);
! 258: fread(top_ten, sizeof(top_ten), 1, fd_score);
! 259:
! 260: /* Insert player in list if need be */
! 261:
! 262: if (!waswizard)
! 263: {
! 264: for (scp = top_ten; scp < &top_ten[10]; scp++)
! 265: {
! 266: if (lvl > scp->sc_lvl)
! 267: break;
! 268:
! 269: if (lvl == scp->sc_lvl && amount > scp->sc_score)
! 270: break;
! 271: }
! 272:
! 273: if (scp < &top_ten[10])
! 274: {
! 275: if (flags == WINNER)
! 276: sc2 = &top_ten[9]; /* LAST WINNER ALWAYS MAKES IT */
! 277:
! 278: while (sc2 > scp)
! 279: {
! 280: *sc2 = sc2[-1];
! 281: sc2--;
! 282: }
! 283:
! 284: scp->sc_lvl = lvl;
! 285: scp->sc_gold = purse;
! 286: scp->sc_score = amount;
! 287: strcpy(scp->sc_name, whoami);
! 288: strcat(scp->sc_name,", ");
! 289: strcat(scp->sc_name, which_class(player.t_ctype));
! 290: scp->sc_flags = flags;
! 291:
! 292: if (flags == WINNER)
! 293: scp->sc_level = max_level;
! 294: else
! 295: scp->sc_level = level;
! 296:
! 297: scp->sc_monster = monst;
! 298: scp->sc_artifacts = has_artifact;
! 299:
! 300: sc2 = scp;
! 301: }
! 302: }
! 303:
! 304: if (flags != SCOREIT)
! 305: {
! 306: clear();
! 307: refresh();
! 308: endwin();
! 309: }
! 310:
! 311: /* Print the list */
! 312:
! 313: printf("\nTop Ten Adventurers:\n%4s %15s %10s %s\n",
! 314: "Rank", "Score", "Gold", "Name");
! 315:
! 316: for (scp = top_ten; scp < &top_ten[10]; scp++)
! 317: {
! 318: if (scp->sc_score)
! 319: {
! 320: char lev[20];
! 321:
! 322: sprintf(lev, "%ld+%ld", scp->sc_lvl, scp->sc_score);
! 323: printf("%4d %15s %10ld %s:", scp - top_ten + 1,
! 324: lev,
! 325: scp->sc_gold,
! 326: scp->sc_name);
! 327:
! 328: if (scp->sc_artifacts)
! 329: {
! 330: char thangs[80];
! 331: int n;
! 332: int first = TRUE;
! 333:
! 334: thangs[0] = '\0';
! 335:
! 336: for (n = 0; n <= maxartifact; n++)
! 337: {
! 338: if (scp->sc_artifacts & (1 << n))
! 339: {
! 340: if (strlen(thangs))
! 341: strcat(thangs, ", ");
! 342:
! 343: if (first)
! 344: {
! 345: strcat(thangs, "retrieved ");
! 346: first = FALSE;
! 347: }
! 348:
! 349: if (45 - strlen(thangs) < strlen(arts[n].ar_name))
! 350: {
! 351: printf("%s\n%32s", thangs," ");
! 352: thangs[0] = '\0';
! 353: }
! 354: strcat(thangs, arts[n].ar_name);
! 355: }
! 356: }
! 357:
! 358: if (strlen(thangs))
! 359: printf("%s,", thangs);
! 360:
! 361: printf("\n%32s"," ");
! 362: }
! 363:
! 364: printf("%s on level %d",reason[scp->sc_flags],scp->sc_level);
! 365:
! 366: if (scp->sc_flags == 0)
! 367: {
! 368: printf(" by \n%32s"," ");
! 369: killer = killname(scp->sc_monster, buf);
! 370: printf(" %s", killer);
! 371: }
! 372:
! 373: putchar('\n');
! 374: }
! 375: }
! 376:
! 377: if (sc2 != NULL)
! 378: {
! 379: fseek(fd_score, 0L, SEEK_SET);
! 380: /* Update the list file */
! 381: fwrite(top_ten, sizeof(top_ten), 1, fd_score);
! 382: }
! 383:
! 384: fclose(fd_score);
! 385:
! 386: if (flags != SCOREIT) {
! 387: printf("[Press RETURN to exit]\n");
! 388: fflush(stdout);
! 389: getchar();
! 390: }
! 391: }
! 392:
! 393: void
! 394: writelog(long amount, int lvl, int flags, int monst)
! 395: {
! 396: char fate[80];
! 397: if (file_log == NULL)
! 398: return;
! 399: if (flags == KILLED) {
! 400: strcpy(fate, "killed by ");
! 401: killname(monst, fate + 10);
! 402: }
! 403: else if (flags == CHICKEN) {
! 404: strcpy(fate, "quit");
! 405: }
! 406: else if (flags == WINNER || flags == TOTAL) {
! 407: strcpy(fate, "escaped");
! 408: }
! 409: else
! 410: return;
! 411: fprintf(file_log, "%ld %ld %s %d %s %d %d %d %s\n", time(NULL), amount,
! 412: whoami, lvl, which_class(player.t_ctype), level, max_level,
! 413: has_artifact, fate);
! 414: fclose(file_log);
! 415: return;
! 416: }
! 417:
! 418: void
! 419: total_winner(void)
! 420: {
! 421: struct linked_list *item;
! 422: struct object *obj;
! 423: int worth, oldpurse;
! 424: char c;
! 425: struct linked_list *bag = NULL;
! 426:
! 427: clear();
! 428: standout();
! 429: addstr(" \n");
! 430: addstr(" @ @ @ @ @ @@@ @ @ \n");
! 431: addstr(" @ @ @@ @@ @ @ @ @ \n");
! 432: addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
! 433: addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
! 434: addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
! 435: addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
! 436: addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
! 437: addstr(" \n");
! 438: addstr(" Congratulations, you have made it to the light of day! \n");
! 439: standend();
! 440: addstr("\nYou have joined the elite ranks of those who have \n");
! 441: addstr("escaped the Dungeons of Doom alive. You journey home \n");
! 442: addstr("and sell all your loot at a great profit.\n");
! 443: addstr("The White Council approves the recommendation of\n");
! 444:
! 445: if (player.t_ctype == C_FIGHTER)
! 446: addstr("the fighters guild and appoints you Lord Protector\n");
! 447: else if (player.t_ctype == C_ASSASIN)
! 448: addstr("the assassins guild and appoints you Master Murderer\n");
! 449: else if (player.t_ctype == C_NINJA)
! 450: addstr("the ninja guild and appoints you Master of the Wind\n");
! 451: else if (player.t_ctype == C_ILLUSION)
! 452: addstr("the illusionists guild and appoints you Master Wizard\n");
! 453: else if (player.t_ctype == C_MAGICIAN)
! 454: addstr("the magicians guild and appoints you Master Wizard\n");
! 455: else if (player.t_ctype == C_CLERIC)
! 456: addstr("the temple priests and appoints you Master of the Flowers\n");
! 457: else if (player.t_ctype == C_DRUID)
! 458: addstr("the temple priests and appoints you Master of the Flowers\n");
! 459: else if (player.t_ctype == C_RANGER)
! 460: addstr("the rangers guild and appoints you Master Ranger\n");
! 461: else if (player.t_ctype == C_PALADIN)
! 462: addstr("the paladins guild and appoints you Master Paladin\n");
! 463: else if (player.t_ctype == C_THIEF)
! 464: {
! 465: addstr("the thieves guild under protest and appoints you\n");
! 466: addstr("Master of the Highways\n");
! 467: }
! 468:
! 469: addstr("of the Land Between the Mountains.\n");
! 470: mvaddstr(LINES - 1, 0, spacemsg);
! 471: refresh();
! 472: wait_for(' ');
! 473: clear();
! 474: idenpack();
! 475: oldpurse = purse;
! 476: mvaddstr(0, 0, " Worth Item");
! 477:
! 478: for (c = 'a', item = pack; item != NULL; c++, item = next(item))
! 479: {
! 480: obj = OBJPTR(item);
! 481: worth = get_worth(obj);
! 482: purse += worth;
! 483:
! 484: if (obj->o_type == ARTIFACT && obj->o_which == TR_PURSE)
! 485: bag = obj->o_bag;
! 486:
! 487: mvprintw(c - 'a' + 1, 0, "%c) %8d %s", c,
! 488: worth, inv_name(obj, UPPERCASE));
! 489: }
! 490:
! 491: if (bag != NULL)
! 492: {
! 493: mvaddstr(LINES - 1, 0, morestr);
! 494: refresh();
! 495: wait_for(' ');
! 496: clear();
! 497: mvprintw(0, 0, "Contents of the Magic Purse of Yendor:\n");
! 498:
! 499: for (c = 'a', item = bag; item != NULL; c++, item = next(item))
! 500: {
! 501: obj = OBJPTR(item);
! 502: worth = get_worth(obj);
! 503: whatis(item);
! 504: purse += worth;
! 505: mvprintw(c - 'a' + 1, 0, "%c) %8d %s\n", c,
! 506: worth, inv_name(obj, UPPERCASE));
! 507: }
! 508: }
! 509:
! 510: mvprintw(c - 'a' + 1, 0, " %6d Gold Pieces ", oldpurse);
! 511: refresh();
! 512:
! 513: if (has_artifact == 255)
! 514: score(pstats.s_exp, pstats.s_lvl, TOTAL, 0);
! 515: else
! 516: score(pstats.s_exp, pstats.s_lvl, WINNER, 0);
! 517:
! 518: byebye();
! 519: }
! 520:
! 521: char *
! 522: killname(int monst, char *buf)
! 523: {
! 524: if (buf == NULL)
! 525: return("A bug in UltraRogue #102");
! 526:
! 527: if (monst >= 0)
! 528: {
! 529: switch (monsters[monst].m_name[0])
! 530: {
! 531: case 'a':
! 532: case 'e':
! 533: case 'i':
! 534: case 'o':
! 535: case 'u':
! 536: sprintf(buf, "an %s", monsters[monst].m_name);
! 537: break;
! 538: default:
! 539: sprintf(buf, "a %s", monsters[monst].m_name);
! 540: }
! 541:
! 542: return(buf);
! 543: }
! 544: else
! 545: switch(monst)
! 546: {
! 547: case D_ARROW:
! 548: strcpy(buf, "an arrow"); break;
! 549: case D_DART:
! 550: strcpy(buf, "a dart"); break;
! 551: case D_BOLT:
! 552: strcpy(buf, "a bolt"); break;
! 553: case D_POISON:
! 554: strcpy(buf, "poison"); break;
! 555: case D_POTION:
! 556: strcpy(buf, "a cursed potion"); break;
! 557: case D_PETRIFY:
! 558: strcpy(buf, "petrification"); break;
! 559: case D_SUFFOCATION:
! 560: strcpy(buf, "suffocation"); break;
! 561: case D_INFESTATION:
! 562: strcpy(buf, "a parasite"); break;
! 563: case D_DROWN:
! 564: strcpy(buf, "drowning"); break;
! 565: case D_FALL:
! 566: strcpy(buf, "falling"); break;
! 567: case D_FIRE:
! 568: strcpy(buf, "slow boiling in oil"); break;
! 569: case D_SPELLFUMBLE:
! 570: strcpy(buf, "a botched spell"); break;
! 571: case D_DRAINLIFE:
! 572: strcpy(buf, "a drain life spell"); break;
! 573: case D_ARTIFACT:
! 574: strcpy(buf, "an artifact of the gods"); break;
! 575: case D_GODWRATH:
! 576: strcpy(buf, "divine retribution"); break;
! 577: case D_CLUMSY:
! 578: strcpy(buf, "excessive clumsyness"); break;
! 579: default:
! 580: strcpy(buf, "stupidity"); break;
! 581: }
! 582:
! 583: return(buf);
! 584: }
! 585:
! 586: /*
! 587: showpack()
! 588: Display the contents of the hero's pack
! 589: */
! 590:
! 591: void
! 592: showpack(char *howso)
! 593: {
! 594: char *iname;
! 595: unsigned int worth;
! 596: int cnt, ch, oldpurse;
! 597: struct linked_list *item;
! 598: struct object *obj;
! 599: struct linked_list *bag = NULL;
! 600:
! 601: cnt = 1;
! 602: clear();
! 603: mvprintw(0, 0, "Contents of your pack %s:\n", howso);
! 604: ch = 0;
! 605: oldpurse = purse;
! 606: purse = 0;
! 607:
! 608: for (item = pack; item != NULL; item = next(item))
! 609: {
! 610: obj = OBJPTR(item);
! 611: worth = get_worth(obj);
! 612: whatis(item);
! 613: purse += worth;
! 614:
! 615: if (obj->o_type == ARTIFACT && obj->o_which == TR_PURSE)
! 616: bag = obj->o_bag;
! 617:
! 618: iname = inv_name(obj, UPPERCASE);
! 619: mvprintw(cnt, 0, "%d) %s\n", ch, iname);
! 620: ch += 1;
! 621:
! 622: if (++cnt > LINES - 5 && next(item) != NULL)
! 623: {
! 624: cnt = 1;
! 625: mvaddstr(LINES - 1, 0, morestr);
! 626: refresh();
! 627: wait_for(' ');
! 628: clear();
! 629: }
! 630: }
! 631:
! 632: if (bag != NULL)
! 633: {
! 634: mvaddstr(LINES - 1, 0, morestr);
! 635: refresh();
! 636: wait_for(' ');
! 637: clear();
! 638: cnt = 1;
! 639: ch = 0;
! 640:
! 641: mvprintw(0, 0, "Contents of the Magic Purse of Yendor %s:\n", howso);
! 642:
! 643: for (item = bag; item != NULL; item = next(item))
! 644: {
! 645: obj = OBJPTR(item);
! 646: worth = get_worth(obj);
! 647: whatis(item);
! 648: purse += worth;
! 649: mvprintw(cnt, 0, "%d) %s\n", ch, inv_name(obj, UPPERCASE));
! 650: ch += 1;
! 651:
! 652: if (++cnt > LINES - 5 && next(item) != NULL)
! 653: {
! 654: cnt = 1;
! 655: mvaddstr(LINES - 1, 0, morestr);
! 656: refresh();
! 657: wait_for(' ');
! 658: clear();
! 659: }
! 660: }
! 661: }
! 662:
! 663: mvprintw(cnt + 1, 0, "Carrying %d gold pieces", oldpurse);
! 664: mvprintw(cnt + 2, 0, "Carrying objects worth %d gold pieces", purse);
! 665: purse += oldpurse;
! 666: refresh();
! 667: }
! 668:
! 669: void
! 670: byebye(void)
! 671: {
! 672: endwin();
! 673: printf("\n");
! 674: exit(0);
! 675: }
! 676:
! 677: /*
! 678: save_resurrect()
! 679: chance of resurrection according to modifed D&D probabilities
! 680: */
! 681:
! 682: int
! 683: save_resurrect(int bonus)
! 684: {
! 685: int need, adjust;
! 686:
! 687: adjust = pstats.s_const + bonus - luck;
! 688:
! 689: if (adjust > 17)
! 690: return(TRUE);
! 691: else if (adjust < 14)
! 692: need = 5 * (adjust + 5);
! 693: else
! 694: need = 90 + 2 * (adjust - 13);
! 695:
! 696: return(roll(1, 100) < need);
! 697: }
CVSweb