Mercurial > hg > early-roguelike
view arogue7/rip.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
line wrap: on
line source
/* * rip.c - File for the fun ends Death or a total win * * Advanced Rogue * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T * All rights reserved. * * Based on "Rogue: Exploring the Dungeons of Doom" * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ /* Print flags for scoring */ #define REALLIFE 1 /* Print out machine and logname */ #define EDITSCORE 2 /* Edit the current score file */ #define ADDSCORE 3 /* Add a new score */ #define NAMELEN 80 /* * File for the fun ends * Death or a total win * */ #include "curses.h" #ifdef BSD #include <sys/time.h> #else #include <time.h> #endif #include <signal.h> #include <ctype.h> #include <sys/types.h> #include <fcntl.h> #include "mach_dep.h" #include "network.h" #include "rogue.h" #ifdef PC7300 #include "sys/window.h" extern struct uwdata wdata, oldwin; extern char oldtext[WTXTNUM][WTXTLEN]; #endif #ifdef NUMNET /* Network machines (for mutual score keeping) */ static struct network Network[NUMNET] = { { "ihwpt", "/t1/michael/bin/rg" }, }; #endif /* * If you change this structure, change the compatibility routines * scoreout() and scorein() to reflect the change. Also update SCORELEN. */ struct sc_ent { unsigned long sc_score; char sc_name[NAMELEN]; char sc_system[SYSLEN]; char sc_login[LOGLEN]; short sc_flags; short sc_level; short sc_ctype; short sc_monster; short sc_quest; }; #define SCORELEN \ (sizeof(unsigned long) + NAMELEN + SYSLEN + LOGLEN + 5*sizeof(short)) static char *rip[] = { " __________", " / \\", " / REST \\", " / IN \\", " / PEACE \\", " / \\", " | |", " | |", " | killed by |", " | |", " | 1984 |", " *| * * * | *", " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______", 0 }; char *killname(); void byebye(sig) int sig; { if (!isendwin()) { clear(); endwin(); } #ifdef PC7300 endhardwin(); #endif printf("\n"); exit(0); } /* * death: * Do something really fun when he dies */ death(monst) register short monst; { register char **dp = rip, *killer; register struct tm *lt; time_t date; char buf[LINELEN]; struct tm *localtime(); time(&date); lt = localtime(&date); clear(); move(8, 0); while (*dp) printw("%s\n", *dp++); mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami); sprintf(buf, "%lu Points", pstats.s_exp ); mvaddstr(15, 28-((strlen(buf)+1)/2), buf); killer = killname(monst); mvaddstr(17, 28-((strlen(killer)+1)/2), killer); mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf)); move(lines-1, 0); refresh(); score(pstats.s_exp, KILLED, monst); endwin(); #ifdef PC7300 endhardwin(); #endif exit(0); } #ifdef PC7300 /* * Restore window characteristics on a hard window terminal (PC7300). */ endhardwin() { register int i; struct utdata labelbuf; /* Restore the old window size */ if (oldwin.uw_width) ioctl(1, WIOCSETD, &oldwin); /* Restore the old window text */ for (i=0; i<WTXTNUM; i++) { labelbuf.ut_num = i; strcpy(labelbuf.ut_text, oldtext[i]); ioctl(1, WIOCSETTEXT, &labelbuf); } } #endif char * killname(monst) register short monst; { static char mons_name[LINELEN]; int i; if (monst > NUMMONST) return("a strange monster"); if (monst >= 0) { switch (monsters[monst].m_name[0]) { case 'a': case 'e': case 'i': case 'o': case 'u': sprintf(mons_name, "an %s", monsters[monst].m_name); break; default: sprintf(mons_name, "a %s", monsters[monst].m_name); } return(mons_name); } for (i = 0; i< DEATHNUM; i++) { if (deaths[i].reason == monst) break; } if (i >= DEATHNUM) return ("strange death"); return (deaths[i].name); } /* * score -- figure score and post it. */ /* VARARGS2 */ score(amount, flags, monst) unsigned long amount; short monst; { static struct sc_ent top_ten[NUMSCORE]; register struct sc_ent *scp; register int i; register struct sc_ent *sc2; register int outfd; register char *killer; register int prflags = 0; register int fd; short upquest, wintype, uplevel, uptype; /* For network updating */ char upsystem[SYSLEN], uplogin[LOGLEN]; char *thissys; /* Holds the name of this system */ char *compatstr=NULL; /* Holds scores for writing compatible score files */ char scoreline[100]; #define REASONLEN 3 static char *reason[] = { "killed", "quit", "A total winner", "somehow left", }; char *packend; signal(SIGINT, byebye); if (flags != WINNER && flags != SCOREIT && flags != UPDATE) { if (flags == CHICKEN) packend = "when you quit"; else { packend = "at your untimely demise"; mvaddstr(lines - 1, 0, retstr); refresh(); getstr(prbuf); } showpack(packend); } purse = 0; /* Steal all the gold */ /* * Open file and read list */ if ((fd = open(score_file, O_RDWR | O_CREAT, 0666)) < 0) return; outfd = fd; #ifndef SYSTEM thissys = md_gethostname(); #else thissys = SYSTEM; #endif for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++) { scp->sc_score = 0L; for (i = 0; i < NAMELEN; i++) scp->sc_name[i] = rnd(255); scp->sc_quest= RN; scp->sc_flags = RN; scp->sc_level = RN; scp->sc_monster = RN; scp->sc_ctype = 0; strncpy(scp->sc_system, thissys, SYSLEN); scp->sc_login[0] = '\0'; } /* * If this is a SCOREIT optin (rogue -s), don't call byebye. The * endwin() call in byebye() will result in a core dump. */ if (flags == SCOREIT) signal(SIGINT, SIG_DFL); else signal(SIGINT, byebye); if (flags != SCOREIT && flags != UPDATE) { mvaddstr(lines - 1, 0, retstr); refresh(); fflush(stdout); getstr(prbuf); } /* Check for special options */ if (strcmp(prbuf, "names") == 0) prflags = REALLIFE; #ifdef WIZARD else if (wizard) { if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE; else if (strcmp(prbuf, "add") == 0) { prflags = ADDSCORE; waswizard = FALSE; /* We want the new score recorded */ } } #endif /* Read the score and convert it to a compatible format */ for(i = 0; i < NUMSCORE; i++) { encread(top_ten[i].sc_name, NAMELEN, fd); encread(top_ten[i].sc_system, SYSLEN, fd); encread(top_ten[i].sc_login, LOGLEN, fd); encread(scoreline, 100, fd); sscanf(scoreline, " %lu %hd %hd %hd %hd %hd \n", &top_ten[i].sc_score, &top_ten[i].sc_flags, &top_ten[i].sc_level, &top_ten[i].sc_ctype, &top_ten[i].sc_monster, &top_ten[i].sc_quest ); } /* Get some values if this is an update */ if (flags == UPDATE) { unsigned long netread(); int errcheck, errors = 0; upquest = (short) netread(&errcheck, sizeof(short), stdin); if (errcheck) errors++; if (fread(whoami, 1, NAMELEN, stdin) != NAMELEN) errors++; wintype = (short) netread(&errcheck, sizeof(short), stdin); if (errcheck) errors++; uplevel = (short) netread(&errcheck, sizeof(short), stdin); if (errcheck) errors++; uptype = (short) netread(&errcheck, sizeof(short), stdin); if (errcheck) errors++; if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN) errors++; if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN) errors++; if (errors) { close(outfd); free(compatstr); return; } } /* * Insert player in list if need be */ if (!waswizard) { char *login; if (flags != UPDATE) { login = md_getusername(); } if (flags == UPDATE) (void) update(top_ten, amount, upquest, whoami, wintype, uplevel, monst, uptype, upsystem, uplogin); else { #ifdef WIZARD if (prflags == ADDSCORE) { /* Overlay characteristic by new ones */ char buffer[LINELEN]; clear(); mvaddstr(1, 0, "Score: "); mvaddstr(2, 0, "Quest (number): "); mvaddstr(3, 0, "Name: "); mvaddstr(4, 0, "System: "); mvaddstr(5, 0, "Login: "); mvaddstr(6, 0, "Level: "); mvaddstr(7, 0, "Char type: "); mvaddstr(8, 0, "Result: "); /* Get the score */ move(1, 7); get_str(buffer, stdscr); amount = atol(buffer); /* Get the character's quest -- must be a number */ move(2, 16); get_str(buffer, stdscr); quest_item = atoi(buffer); /* Get the character's name */ move(3, 6); get_str(buffer, stdscr); strncpy(whoami, buffer, NAMELEN); /* Get the system */ move(4, 8); get_str(buffer, stdscr); strncpy(thissys, buffer, SYSLEN); /* Get the login */ move(5, 7); get_str(buffer, stdscr); strncpy(login, buffer, LOGLEN); /* Get the level */ move(6, 7); get_str(buffer, stdscr); level = max_level = (short) atoi(buffer); /* Get the character type */ move(7, 11); get_str(buffer, stdscr); for (i=0; i<NUM_CHARTYPES; i++) { if (EQSTR(buffer, char_class[i].name, strlen(buffer))) break; } player.t_ctype = i; /* Get the win type */ move(8, 8); get_str(buffer, stdscr); switch (buffer[0]) { case 'W': case 'w': case 'T': case 't': flags = WINNER; break; case 'Q': case 'q': flags = CHICKEN; break; case 'k': case 'K': default: flags = KILLED; break; } /* Get the monster if player was killed */ if (flags == KILLED) { mvaddstr(9, 0, "Death type: "); get_str(buffer, stdscr); if (buffer[0] == 'M' || buffer[0] == 'm') do { monst = makemonster(TRUE, "Editing", "choose"); } while (monst < 0); /* Force a choice */ else monst = getdeath(); } } #endif if (update(top_ten, amount, (short) quest_item, whoami, flags, (flags == WINNER) ? (short) max_level : (short) level, monst, player.t_ctype, thissys, login) #ifdef NUMNET && fork() == 0 /* Spin off network process */ #endif ) { #ifdef NUMNET /* Send this update to the other systems in the network */ int i, j; char cmd[256]; /* Command for remote execution */ FILE *rmf, *popen(); /* For input to remote command */ for (i=0; i<NUMNET; i++) if (Network[i].system[0] != '!' && strcmp(Network[i].system, thissys)) { sprintf(cmd, NETCOMMAND, Network[i].system, Network[i].rogue); /* Execute the command */ if ((rmf=popen(cmd, "w")) != NULL) { unsigned long temp; /* Temporary value */ /* Write out the parameters */ (void) netwrite((unsigned long) amount, sizeof(unsigned long), rmf); (void) netwrite((unsigned long) monst, sizeof(short), rmf); (void) netwrite((unsigned long) quest_item, sizeof(short), rmf); (void) fwrite(whoami, 1, strlen(whoami), rmf); for (j=strlen(whoami); j<NAMELEN; j++) putc('\0', rmf); (void) netwrite((unsigned long) flags, sizeof(short), rmf);