Mercurial > hg > early-roguelike
view rogue5/rip.c @ 88:07c4d4883ef2
rogue3: begin porting to autoconf.
Rogue V3 can now be built with './configure && make'. This is
preliminary: 'make install' does not work yet.
author | John "Elwin" Edwards |
---|---|
date | Sat, 24 Aug 2013 13:36:13 -0700 |
parents | 24e6beb9e7aa |
children | ee250e3646fd |
line wrap: on
line source
/* * File for the fun ends * Death or a total win * * @(#)rip.c 4.57 (Berkeley) 02/05/99 * * Rogue: Exploring the Dungeons of Doom * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include <stdlib.h> #include <string.h> #include <time.h> #include <signal.h> #include <sys/types.h> #include <ctype.h> #include <fcntl.h> #include <curses.h> #include "rogue.h" #include "score.h" static char *rip[] = { " __________\n", " / \\\n", " / REST \\\n", " / IN \\\n", " / PEACE \\\n", " / \\\n", " | |\n", " | |\n", " | killed by a |\n", " | |\n", " | 1980 |\n", " *| * * * | *\n", " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n", 0 }; /* * score: * Figure score and post it. */ /* VARARGS2 */ void score(int amount, int flags, int monst) { SCORE *scp; int i; SCORE *sc2; SCORE *top_ten, *endp; # ifdef MASTER int prflags = 0; # endif void (*fp)(int); uid_t uid; char *reason[] = { "killed", "quit", "A total winner", "killed with Amulet" }; start_score(); if (flags >= 0 #ifdef MASTER || wizard #endif ) { mvaddstr(LINES - 1, 0 , "[Press return to continue]"); refresh(); wgetnstr(stdscr,prbuf,80); endwin(); printf("\n"); resetltchars(); /* * free up space to "guarantee" there is space for the top_ten */ delwin(stdscr); delwin(curscr); if (hw != NULL) delwin(hw); } top_ten = malloc(numscores * sizeof (SCORE)); if (top_ten == NULL) return; endp = &top_ten[numscores]; for (scp = top_ten; scp < endp; scp++) { scp->sc_score = 0; for (i = 0; i < MAXSTR; i++) scp->sc_name[i] = (char) rnd(255); scp->sc_flags = RN; scp->sc_level = RN; scp->sc_monster = RN; scp->sc_uid = RN; } signal(SIGINT, SIG_DFL); #ifdef MASTER if (wizard) if (strcmp(prbuf, "names") == 0) prflags = 1; else if (strcmp(prbuf, "edit") == 0) prflags = 2; #endif rd_score(top_ten); /* * Insert her in list if need be */ sc2 = NULL; if (!noscore) { uid = md_getuid(); for (scp = top_ten; scp < endp; scp++) if (amount > scp->sc_score) break; else if (!allscore && /* only one score per nowin uid */ flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2) scp = endp; if (scp < endp) { if (flags != 2 && !allscore) { for (sc2 = scp; sc2 < endp; sc2++) { if (sc2->sc_uid == uid && sc2->sc_flags != 2) break; } if (sc2 >= endp) sc2 = endp - 1; } else sc2 = endp - 1; while (sc2 > scp) { *sc2 = sc2[-1]; sc2--; } scp->sc_score = amount; strncpy(scp->sc_name, whoami, MAXSTR); scp->sc_flags = flags; if (flags == 2) scp->sc_level = max_level; else scp->sc_level = level; scp->sc_monster = monst; scp->sc_uid = uid; sc2 = scp; } } /* * Print the list */ if (flags != -1) putchar('\n'); printf("Top %s %s:\n", Numname, allscore ? "Scores" : "Rogueists"); printf(" Score Name\n"); for (scp = top_ten; scp < endp; scp++) { if (scp->sc_score) { if (sc2 == scp) md_raw_standout(); printf("%2d %5d %s: %s on level %d", (int) (scp - top_ten + 1), scp->sc_score, scp->sc_name, reason[scp->sc_flags], scp->sc_level); if (scp->sc_flags == 0 || scp->sc_flags == 3) printf(" by %s", killname(scp->sc_monster, TRUE)); #ifdef MASTER if (prflags == 1) { printf(" (%s)", md_getrealname(scp->sc_uid)); } else if (prflags == 2) { fflush(stdout); (void) fgets(prbuf,10,stdin); if (prbuf[0] == 'd') { for (sc2 = scp; sc2 < endp - 1; sc2++) *sc2 = *(sc2 + 1); sc2 = endp - 1; sc2->sc_score = 0; for (i = 0; i < MAXSTR; i++) sc2->sc_name[i] = (char) rnd(255); sc2->sc_flags = RN; sc2->sc_level = RN; sc2->sc_monster = RN; scp--; } } else #endif /* MASTER */ printf("."); if (sc2 == scp) md_raw_standend(); putchar('\n'); } else break; } /* * Update the list file */ if (sc2 != NULL) { if (lock_sc()) { fp = signal(SIGINT, SIG_IGN); wr_score(top_ten); unlock_sc(); signal(SIGINT, fp); } } } void writelog(int amount, int flags, int monst) { #ifdef LOGFILE char logmessage[160], ltemp[80]; if (logfi == NULL) return; #ifdef MASTER if (wizard) { fclose(logfi); return; } #endif sprintf(logmessage, "%d %d %.20s %d ", time(NULL), amount, whoami, pstats.s_lvl); if (flags == 0) /* dead */ { sprintf(ltemp, "killed by %s on level %d\n", killname(monst, TRUE), level); strcat(logmessage, ltemp); } else if (flags == 1) /* quit */ { if (amulet) sprintf(ltemp, "quit on level %d [max %d] with the Amulet\n", level, max_level); else sprintf(ltemp, "quit on level %d\n", level); strcat(logmessage, ltemp); } else if (flags == 2) /* won */ { sprintf(ltemp, "escaped with the Amulet [deepest level: %d]\n", max_level); strcat(logmessage, ltemp); } else if (flags == 3) /* killed with Amulet */ { strcat(logmessage, "killed by "); strcat(logmessage, killname(monst, TRUE)); sprintf(ltemp, " on level %d [max %d] with the Amulet\n", level, max_level); strcat(logmessage, ltemp); } else { fclose(logfi); return; } fprintf(logfi, "%s", logmessage); fclose(logfi); #endif return; } /* * death: * Do something really fun when he dies */ void death(int monst) { char **dp; const char *killer; struct tm *lt; time_t date; signal(SIGINT, SIG_IGN); purse -= purse / 10; signal(SIGINT, leave); clear(); killer = killname(monst, FALSE); if (!tombstone) { mvprintw(LINES - 2, 0, "Killed by "); killer = killname(monst, FALSE); if (monst != 's' && monst != 'h') printw("a%s ", vowelstr(killer)); printw("%s with %d gold", killer, purse); } else { time(&date); lt = localtime(&date); move(8, 0); dp = rip; while (*dp) addstr(*dp++); mvaddstr(17, center(killer), killer); if (monst == 's' || monst == 'h') mvaddch(16, 32, ' '); else mvaddstr(16, 33, vowelstr(killer)); mvaddstr(14, center(whoami), whoami); sprintf(prbuf, "%d Au", purse); move(15, center(prbuf)); addstr(prbuf); sprintf(prbuf, "%4d", 1900+lt->tm_year); mvaddstr(18, 26, prbuf); } move(LINES - 1, 0); refresh(); writelog(purse, amulet ? 3 : 0, monst); score(purse, amulet ? 3 : 0, monst); /* Make sure the output gets through. */ printf("[Press return to exit]\n"); fflush(NULL); getchar(); my_exit(0); } /* * center: * Return the index to center the given string */ int center(const char *str) { return 28 - (((int)strlen(str) + 1) / 2); } /* * total_winner: * Code for a winner */ void total_winner(void) { THING *obj; struct obj_info *op; int worth = 0; int oldpurse; clear(); standout(); addstr(" \n"); addstr(" @ @ @ @ @ @@@ @ @ \n"); addstr(" @ @ @@ @@ @ @ @ @ \n"); addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n"); addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n"); addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n"); addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n"); addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n"); addstr(" \n"); addstr(" Congratulations, you have made it to the light of day! \n"); standend(); addstr("\nYou have joined the elite ranks of those who have escaped the\n"); addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n"); addstr("a great profit and are admitted to the Fighters' Guild.\n"); mvaddstr(LINES - 1, 0, "--Press space to continue--"); refresh(); wait_for(stdscr, ' '); clear(); mvaddstr(0, 0, " Worth Item\n"); oldpurse = purse; for (obj = pack; obj != NULL; obj = next(obj)) { switch (obj->o_type) { case FOOD: worth = 2 * obj->o_count; when WEAPON: worth = weap_info[obj->o_which].oi_worth; worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count; obj->o_flags |= ISKNOW; when ARMOR: worth = arm_info[obj->o_which].oi_worth; worth += (9 - obj->o_arm) * 100; worth += (10 * (a_class[obj->o_which] - obj->o_arm)); obj->o_flags |= ISKNOW; when SCROLL: worth = scr_info[obj->o_which].oi_worth; worth *= obj->o_count; op = &scr_info[obj->o_which]; if (!op->oi_know) worth /= 2; op->oi_know = TRUE; when POTION: worth = pot_info[obj->o_which].oi_worth; worth *= obj->o_count; op = &pot_info[obj->o_which]; if (!op->oi_know) worth /= 2; op->oi_know = TRUE; when RING: op = &ring_info[obj->o_which]; worth = op->oi_worth; if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM || obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT) { if (obj->o_arm > 0) worth += obj->o_arm * 100; else worth = 10; } if (!(obj->o_flags & ISKNOW)) worth /= 2; obj->o_flags |= ISKNOW; op->oi_know = TRUE; when STICK: op = &ws_info[obj->o_which]; worth = op->oi_worth; worth += 20 * obj->o_charges; if (!(obj->o_flags & ISKNOW)) worth /= 2; obj->o_flags |= ISKNOW; op->oi_know = TRUE; when AMULET: worth = 1000; } if (worth < 0) worth = 0; printw("%c) %5d %s\n", obj->o_packch, worth, inv_name(obj, FALSE)); purse += worth; } printw(" %5d Gold Pieces ", oldpurse); refresh(); writelog(purse, 2, ' '); score(purse, 2, ' '); printf("[Press return to exit]\n"); fflush(NULL); getchar(); my_exit(0); } /* * killname: * Convert a code to a monster name */ const char * killname(int monst, int doart) { struct h_list *hp; const char *sp; int article; struct h_list nlist[] = { {'a', "arrow", TRUE}, {'b', "bolt", TRUE}, {'d', "dart", TRUE}, {'h', "hypothermia", FALSE}, {'s', "starvation", FALSE}, {'\0'} }; if (isupper(monst)) { sp = monsters[monst-'A'].m_name; article = TRUE; } else { sp = "Wally the Wonder Badger"; article = FALSE; for (hp = nlist; hp->h_ch; hp++) if (hp->h_ch == monst) { sp = hp->h_desc; article = hp->h_print; break; } } if (doart && article) sprintf(prbuf, "a%s ", vowelstr(sp)); else prbuf[0] = '\0'; strcat(prbuf, sp); return prbuf; } /* * death_monst: * Return a monster appropriate for a random death. */ int death_monst(void) { int poss[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'h', 'd', 's', ' ' /* This is provided to generate the "Wally the Wonder Badger" message for killer */ }; return poss[rnd(sizeof poss / sizeof (int))]; }