Annotation of early-roguelike/arogue7/rip.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: * rip.c - File for the fun ends Death or a total win
3: *
4: * Advanced Rogue
5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
6: * All rights reserved.
7: *
8: * Based on "Rogue: Exploring the Dungeons of Doom"
9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
10: * All rights reserved.
11: *
12: * See the file LICENSE.TXT for full copyright and licensing information.
13: */
14:
15: /* Print flags for scoring */
16: #define REALLIFE 1 /* Print out machine and logname */
17: #define EDITSCORE 2 /* Edit the current score file */
18: #define ADDSCORE 3 /* Add a new score */
19:
20: #define NAMELEN 80
21:
22: /*
23: * File for the fun ends
24: * Death or a total win
25: *
26: */
27:
28: #include "curses.h"
29: #ifdef BSD
30: #include <sys/time.h>
31: #else
32: #include <time.h>
33: #endif
34: #include <signal.h>
35: #include <ctype.h>
36: #include <string.h>
37: #include <stdlib.h>
38: #include <sys/types.h>
39: #include <fcntl.h>
40: #include "mach_dep.h"
41: #include "network.h"
42: #include "rogue.h"
43: #ifdef PC7300
44: #include "sys/window.h"
45: extern struct uwdata wdata, oldwin;
46: extern char oldtext[WTXTNUM][WTXTLEN];
47: #endif
48:
49: #ifdef NUMNET
50: /* Network machines (for mutual score keeping) */
51: static struct network Network[NUMNET] = {
52: { "ihwpt", "/t1/michael/bin/rg" },
53: };
54: #endif
55:
56: /*
57: * If you change this structure, change the compatibility routines
58: * scoreout() and scorein() to reflect the change. Also update SCORELEN.
59: */
60: struct sc_ent {
61: unsigned long sc_score;
62: char sc_name[NAMELEN];
63: char sc_system[SYSLEN];
64: char sc_login[LOGLEN];
65: short sc_flags;
66: short sc_level;
67: short sc_ctype;
68: short sc_monster;
69: short sc_quest;
70: };
71: #define SCORELEN \
72: (sizeof(unsigned long) + NAMELEN + SYSLEN + LOGLEN + 5*sizeof(short))
73:
74: static char *rip[] = {
75: " __________",
76: " / \\",
77: " / REST \\",
78: " / IN \\",
79: " / PEACE \\",
80: " / \\",
81: " | |",
82: " | |",
83: " | killed by |",
84: " | |",
85: " | 1984 |",
86: " *| * * * | *",
87: " ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
88: 0
89: };
90:
91: char *killname(short monst);
92: void showpack(char *howso);
93: int update(struct sc_ent top_ten[], unsigned long amount, short quest,
94: char *whoami, short flags, short level, short monst, short ctype,
95: char *system, char *login);
96:
97:
98: void
99: byebye(int sig)
100: {
101: if (!isendwin()) {
102: clear();
103: endwin();
104: }
105: #ifdef PC7300
106: endhardwin();
107: #endif
108: printf("\n");
109: exit(0);
110: }
111:
112:
113: /*
114: * death:
115: * Do something really fun when he dies
116: */
117:
118: void
119: death(short monst)
120: {
121: register char **dp = rip, *killer;
122: register struct tm *lt;
123: time_t date;
124: char buf[LINELEN];
125: struct tm *localtime();
126:
127: time(&date);
128: lt = localtime(&date);
129: clear();
130: move(8, 0);
131: while (*dp)
132: printw("%s\n", *dp++);
133: mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami);
134: sprintf(buf, "%lu Points", pstats.s_exp );
135: mvaddstr(15, 28-((strlen(buf)+1)/2), buf);
136: killer = killname(monst);
137: mvaddstr(17, 28-((strlen(killer)+1)/2), killer);
138: mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf));
139: move(lines-1, 0);
140: refresh();
141: writelog(pstats.s_exp, KILLED, monst);
142: score(pstats.s_exp, KILLED, monst);
143: endwin();
144: #ifdef PC7300
145: endhardwin();
146: #endif
147: exit(0);
148: }
149:
150: #ifdef PC7300
151: /*
152: * Restore window characteristics on a hard window terminal (PC7300).
153: */
154: void
155: endhardwin(void)
156: {
157: register int i;
158: struct utdata labelbuf;
159:
160: /* Restore the old window size */
161: if (oldwin.uw_width) ioctl(1, WIOCSETD, &oldwin);
162:
163: /* Restore the old window text */
164: for (i=0; i<WTXTNUM; i++) {
165: labelbuf.ut_num = i;
166: strcpy(labelbuf.ut_text, oldtext[i]);
167: ioctl(1, WIOCSETTEXT, &labelbuf);
168: }
169: }
170: #endif
171:
172: char *
173: killname(short monst)
174: {
175: static char mons_name[LINELEN];
176: int i;
177:
178: if (monst > NUMMONST) return("a strange monster");
179:
180: if (monst >= 0) {
181: switch (monsters[monst].m_name[0]) {
182: case 'a':
183: case 'e':
184: case 'i':
185: case 'o':
186: case 'u':
187: sprintf(mons_name, "an %s", monsters[monst].m_name);
188: break;
189: default:
190: sprintf(mons_name, "a %s", monsters[monst].m_name);
191: }
192: return(mons_name);
193: }
194: for (i = 0; i< DEATHNUM; i++) {
195: if (deaths[i].reason == monst)
196: break;
197: }
198: if (i >= DEATHNUM)
199: return ("strange death");
200: return (deaths[i].name);
201: }
202:
203: /* Writes an entry in the log file */
204:
205: void
206: writelog(unsigned long amount, int flags, short monst)
207: {
208: char had_quest = '0';
209: char fate[LINELEN];
210: struct linked_list *item;
211: struct object *obj;
212: #ifdef LOGFILE
213: if (waswizard)
214: return;
215: if (logfile == NULL)
216: return;
217: /* Check for quest item */
218: for (item = pack; item != NULL; item = next(item)) {
219: obj = OBJPTR(item);
220: if (obj->o_type == RELIC && obj->o_which == quest_item)
221: had_quest = '1';
222: }
223: /* Describe what happened */
224: if (flags == KILLED) {
225: snprintf(fate, LINELEN, "killed by %s", killname(monst));
226: }
227: else if (flags == CHICKEN) {
228: strcpy(fate, "quit");
229: }
230: else if (flags == WINNER) {
231: strcpy(fate, "escaped");
232: }
233: else
234: return;
235: /* Write */
236: fprintf(logfile, "%ld %ld %s %d %s %d %d %d %c %s\n", time(NULL), amount,
237: whoami, pstats.s_lvl, char_class[char_type].name, level, max_level,
238: quest_item, had_quest, fate);
239: fclose(logfile);
240: #endif
241: return;
242: }
243:
244: /*
245: * score -- figure score and post it.
246: */
247:
248: /* VARARGS2 */
249: void
250: score(unsigned long amount, int flags, short monst)
251: {
252: static struct sc_ent top_ten[NUMSCORE];
253: register struct sc_ent *scp;
254: register int i;
255: register struct sc_ent *sc2;
256: register char *killer;
257: register int prflags = 0;
258: short upquest, wintype, uplevel, uptype; /* For network updating */
259: char upsystem[SYSLEN], uplogin[LOGLEN];
260: char *thissys; /* Holds the name of this system */
261: char *compatstr=NULL; /* Holds scores for writing compatible score files */
262: char scoreline[100];
263: #define REASONLEN 3
264: static char *reason[] = {
265: "killed",
266: "quit",
267: "A total winner",
268: "somehow left",
269: };
270: char *packend;
271:
272: signal(SIGINT, byebye);
273: if (flags != WINNER && flags != SCOREIT && flags != UPDATE) {
274: if (flags == CHICKEN)
275: packend = "when you quit";
276: else
277: {
278: packend = "at your untimely demise";
279: mvaddstr(lines - 1, 0, retstr);
280: refresh();
281: getstr(prbuf);
282: }
283: showpack(packend);
284: }
285: purse = 0; /* Steal all the gold */
286:
287: /*
288: * Read list
289: */
290:
291: if (scoreboard == NULL) return;
292:
293: #ifndef SYSTEM
294: thissys = md_gethostname();
295: #else
296: thissys = SYSTEM;
297: #endif
298:
299: for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++)
300: {
301: scp->sc_score = 0L;
302: for (i = 0; i < NAMELEN; i++)
303: scp->sc_name[i] = rnd(255);
304: scp->sc_quest= RN;
305: scp->sc_flags = RN;
306: scp->sc_level = RN;
307: scp->sc_monster = RN;
308: scp->sc_ctype = 0;
309: strncpy(scp->sc_system, thissys, SYSLEN);
310: scp->sc_login[0] = '\0';
311: }
312:
313: /*
314: * If this is a SCOREIT optin (rogue -s), don't call byebye. The
315: * endwin() call in byebye() will result in a core dump.
316: */
317: if (flags == SCOREIT) signal(SIGINT, SIG_DFL);
318: else signal(SIGINT, byebye);
319:
320: if (flags != SCOREIT && flags != UPDATE)
321: {
322: mvaddstr(lines - 1, 0, retstr);
323: refresh();
324: fflush(stdout);
325: getstr(prbuf);
326: }
327:
328: /* Check for special options */
329: if (strcmp(prbuf, "names") == 0)
330: prflags = REALLIFE;
331: #ifdef WIZARD
332: else if (wizard) {
333: if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE;
334: else if (strcmp(prbuf, "add") == 0) {
335: prflags = ADDSCORE;
336: waswizard = FALSE; /* We want the new score recorded */
337: }
338: }
339: #endif
340:
341: /* Read the score and convert it to a compatible format */
342: for(i = 0; i < NUMSCORE; i++)
343: {
344: encread(top_ten[i].sc_name, NAMELEN, scoreboard);
345: encread(top_ten[i].sc_system, SYSLEN, scoreboard);
346: encread(top_ten[i].sc_login, LOGLEN, scoreboard);
347: encread(scoreline, 100, scoreboard);
348: sscanf(scoreline, " %lu %hd %hd %hd %hd %hd \n",
349: &top_ten[i].sc_score, &top_ten[i].sc_flags,
350: &top_ten[i].sc_level, &top_ten[i].sc_ctype,
351: &top_ten[i].sc_monster, &top_ten[i].sc_quest
352: );
353: }
354:
355: /* Get some values if this is an update */
356: if (flags == UPDATE) {
357: unsigned long netread();
358: int errcheck, errors = 0;
359:
360: upquest = (short) netread(&errcheck, sizeof(short), stdin);
361: if (errcheck) errors++;
362:
363: if (fread(whoami, 1, NAMELEN, stdin) != NAMELEN) errors++;
364:
365: wintype = (short) netread(&errcheck, sizeof(short), stdin);
366: if (errcheck) errors++;
367:
368: uplevel = (short) netread(&errcheck, sizeof(short), stdin);
369: if (errcheck) errors++;
370:
371: uptype = (short) netread(&errcheck, sizeof(short), stdin);
372: if (errcheck) errors++;
373:
374: if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN)
375: errors++;
376: if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN)
377: errors++;
378:
379: if (errors) {
380: fclose(scoreboard);
381: free(compatstr);
382: return;
383: }
384: }
385:
386: /*
387: * Insert player in list if need be
388: */
389: if (!waswizard) {
390: char *login = "";
391:
392: if (flags != UPDATE) {
393: login = md_getusername();
394: }
395:
396: if (flags == UPDATE)
397: (void) update(top_ten, amount, upquest, whoami, wintype,
398: uplevel, monst, uptype, upsystem, uplogin);
399: else {
400: #ifdef WIZARD
401: if (prflags == ADDSCORE) { /* Overlay characteristic by new ones */
402: char buffer[LINELEN];
403:
404: clear();
405: mvaddstr(1, 0, "Score: ");
406: mvaddstr(2, 0, "Quest (number): ");
407: mvaddstr(3, 0, "Name: ");
408: mvaddstr(4, 0, "System: ");
409: mvaddstr(5, 0, "Login: ");
410: mvaddstr(6, 0, "Level: ");
411: mvaddstr(7, 0, "Char type: ");
412: mvaddstr(8, 0, "Result: ");
413:
414: /* Get the score */
415: move(1, 7);
416: get_str(buffer, stdscr);
417: amount = atol(buffer);
418:
419: /* Get the character's quest -- must be a number */
420: move(2, 16);
421: get_str(buffer, stdscr);
422: quest_item = atoi(buffer);
423:
424: /* Get the character's name */
425: move(3, 6);
426: get_str(buffer, stdscr);
427: strncpy(whoami, buffer, NAMELEN);
428:
429: /* Get the system */
430: move(4, 8);
431: get_str(buffer, stdscr);
432: strncpy(thissys, buffer, SYSLEN);
433:
434: /* Get the login */
435: move(5, 7);
436: get_str(buffer, stdscr);
437: strncpy(login, buffer, LOGLEN);
438:
439: /* Get the level */
440: move(6, 7);
441: get_str(buffer, stdscr);
442: level = max_level = (short) atoi(buffer);
443:
444: /* Get the character type */
445: move(7, 11);
446: get_str(buffer, stdscr);
447: for (i=0; i<NUM_CHARTYPES; i++) {
448: if (EQSTR(buffer, char_class[i].name, strlen(buffer)))
449: break;
450: }
451: player.t_ctype = i;
452:
453: /* Get the win type */
454: move(8, 8);
455: get_str(buffer, stdscr);
456: switch (buffer[0]) {
457: case 'W':
458: case 'w':
459: case 'T':
460: case 't':
461: flags = WINNER;
462: break;
463:
464: case 'Q':
465: case 'q':
466: flags = CHICKEN;
467: break;
468:
469: case 'k':
470: case 'K':
471: default:
472: flags = KILLED;
473: break;
474: }
475:
476: /* Get the monster if player was killed */
477: if (flags == KILLED) {
478: mvaddstr(9, 0, "Death type: ");
479: get_str(buffer, stdscr);
480: if (buffer[0] == 'M' || buffer[0] == 'm')
481: do {
482: monst = makemonster(TRUE, "Editing", "choose");
483: } while (monst < 0); /* Force a choice */
484: else monst = getdeath();
485: }
486: }
487: #endif
488:
489: if (update(top_ten, amount, (short) quest_item, whoami, flags,
490: (flags == WINNER) ? (short) max_level : (short) level,
491: monst, player.t_ctype, thissys, login)
492: #ifdef NUMNET
493: && fork() == 0 /* Spin off network process */
494: #endif
495: ) {
496: #ifdef NUMNET
497: /* Send this update to the other systems in the network */
498: int i, j;
499: char cmd[256]; /* Command for remote execution */
500: FILE *rmf, *popen(); /* For input to remote command */
501:
502: for (i=0; i<NUMNET; i++)
503: if (Network[i].system[0] != '!' &&
504: strcmp(Network[i].system, thissys)) {
505: sprintf(cmd, NETCOMMAND,
506: Network[i].system, Network[i].rogue);
507:
508: /* Execute the command */
509: if ((rmf=popen(cmd, "w")) != NULL) {
510: unsigned long temp; /* Temporary value */
511:
512: /* Write out the parameters */
513: (void) netwrite((unsigned long) amount,
514: sizeof(unsigned long), rmf);
515:
516: (void) netwrite((unsigned long) monst,
517: sizeof(short), rmf);
518:
519: (void) netwrite((unsigned long) quest_item,
520: sizeof(short), rmf);
521:
522: (void) fwrite(whoami, 1, strlen(whoami), rmf);
523: for (j=strlen(whoami); j<NAMELEN; j++)
524: putc('\0', rmf);
525:
526: (void) netwrite((unsigned long) flags,
527: sizeof(short), rmf);
528:
529: temp = (unsigned long)
530: (flags==WINNER ? max_level : level);
531: (void) netwrite(temp, sizeof(short), rmf);
532:
533: (void) netwrite((unsigned long) player.t_ctype,
534: sizeof(short), rmf);
535:
536: (void) fwrite(thissys, 1,
537: strlen(thissys), rmf);
538: for (j=strlen(thissys); j<SYSLEN; j++)
539: putc('\0', rmf);
540:
541: (void) fwrite(login, 1, strlen(login), rmf);
542: for (j=strlen(login); j<LOGLEN; j++)
543: putc('\0', rmf);
544:
545: /* Close off the command */
546: (void) pclose(rmf);
547: }
548: }
549: _exit(0); /* Exit network process */
550: #endif
551: }
552: }
553: }
554:
555: /*
556: * SCOREIT -- rogue -s option. Never started curses if this option.
557: * UPDATE -- network scoring update. Never started curses if this option.
558: * EDITSCORE -- want to delete or change a score.
559: */
560: /* if (flags != SCOREIT && flags != UPDATE && prflags != EDITSCORE)
561: endwin(); */
562:
563: if (flags != UPDATE) {
564: if (flags != SCOREIT) {
565: clear();
566: refresh();
567: endwin();
568: }
569: /*
570: * Print the list
571: */
572: printf("\nTop %d Adventurers:\nRank Score\tName\n",
573: NUMSCORE);
574: for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++) {
575: const char *class;
576:
577: if (scp->sc_score != 0) {
578: class = char_class[scp->sc_ctype].name;
579:
580: /* Make sure we have an in-bound reason */
581: if (scp->sc_flags > REASONLEN) scp->sc_flags = REASONLEN;
582:
583: printf("%3d %10lu\t%s (%s)", scp - top_ten + 1,
584: scp->sc_score, scp->sc_name, class);
585:
586: if (prflags == REALLIFE) printf(" [in real life %.*s!%.*s]",
587: SYSLEN, scp->sc_system, LOGLEN, scp->sc_login);
588: printf(":\n\t\t%s on level %d", reason[scp->sc_flags],
589: scp->sc_level);
590:
591: switch (scp->sc_flags) {
592: case KILLED:
593: printf(" by");
594: killer = killname(scp->sc_monster);
595: printf(" %s", killer);
596: break;
597:
598: case WINNER:
599: printf(" with the %s",
600: rel_magic[scp->sc_quest].mi_name);
601: break;
602: }
603:
604: if (prflags == EDITSCORE)
605: {
606: fflush(stdout);
607: getstr(prbuf);
608: printf("\n");
609: if (prbuf[0] == 'd') {
610: for (sc2 = scp; sc2 < &top_ten[NUMSCORE-1]; sc2++)
611: *sc2 = *(sc2 + 1);
612: top_ten[NUMSCORE-1].sc_score = 0;
613: for (i = 0; i < NAMELEN; i++)
614: top_ten[NUMSCORE-1].sc_name[i] = rnd(255);
615: top_ten[NUMSCORE-1].sc_flags = RN;
616: top_ten[NUMSCORE-1].sc_level = RN;
617: top_ten[NUMSCORE-1].sc_monster = RN;
618: scp--;
619: }
620: else if (prbuf[0] == 'e') {
621: printf("Death type: ");
622: getstr(prbuf);
623: if (prbuf[0] == 'M' || prbuf[0] == 'm')
624: do {
625: scp->sc_monster =
626: makemonster(TRUE, "Editing", "choose");
627: } while (scp->sc_monster < 0); /* Force a choice */
628: else scp->sc_monster = getdeath();
629: clear();
630: refresh();
631: }
632: }
633: else printf("\n");
634: }
635: }
636: if ((flags != SCOREIT) && (flags != UPDATE)) {
637: printf("\n[Press return to exit]");
638: fflush(stdout);
639: fgets(prbuf,80,stdin);
640: }
641: /* if (prflags == EDITSCORE) endwin();*/ /* End editing windowing */
642: }
643: fseek(scoreboard, 0L, SEEK_SET);
644: /*
645: * Update the list file
646: */
647:
648: for(i = 0; i < NUMSCORE; i++)
649: {
650: memset(scoreline,0,100);
651: encwrite(top_ten[i].sc_name, NAMELEN, scoreboard);
652: encwrite(top_ten[i].sc_system, SYSLEN, scoreboard);
653: encwrite(top_ten[i].sc_login, LOGLEN, scoreboard);
654: sprintf(scoreline, " %lu %hd %hd %hd %hd %hd \n",
655: top_ten[i].sc_score, top_ten[i].sc_flags,
656: top_ten[i].sc_level, top_ten[i].sc_ctype,
657: top_ten[i].sc_monster, top_ten[i].sc_quest);
658: encwrite(scoreline,100,scoreboard);
659: }
660:
661: fclose(scoreboard);
662: }
663:
664: /*
665: * scorein:
666: * Convert a character string that has been translated from a
667: * score file by scoreout() back to a score file structure.
668: * num_bytes: Number of bytes of input that we want to convert
669: */
670: void
671: scorein(unsigned char *input, struct sc_ent scores[], int num_bytes)
672: {
673: register int i, j;
674: unsigned long *lptr;
675: unsigned short *sptr;
676: unsigned char *cptr;
677:
678: /* Convert a maximum of NUMSCORE entries */
679: for (i=0; num_bytes > 0 && i < NUMSCORE; num_bytes -= SCORELEN, i++) {
680: /* The long fields are first -- ordered low to high byte in input */
681: lptr = &scores[i].sc_score;
682: *lptr = ((unsigned long) *input++) & 0x000000ffL;
683: *lptr |= (((unsigned long) *input++) << 8) & 0x0000ff00L;
684: *lptr |= (((unsigned long) *input++) << 16) & 0x00ff0000L;
685: *lptr |= (((unsigned long) *input++) << 24) & 0xff000000L;
686:
687: /* The short fields are next -- ordered low to high byte in input */
688: sptr = (unsigned short *) &scores[i].sc_flags;
689: *sptr = ((unsigned short) *input++) & 0xff;
690: *sptr |= (((unsigned short) *input++) << 8) & 0xff00;
691:
692: sptr = (unsigned short *) &scores[i].sc_level;
693: *sptr = ((unsigned short) *input++) & 0xff;
694: *sptr |= (((unsigned short) *input++) << 8) & 0xff00;
695:
696: sptr = (unsigned short *) &scores[i].sc_ctype;
697: *sptr = ((unsigned short) *input++) & 0xff;
698: *sptr |= (((unsigned short) *input++) << 8) & 0xff00;
699:
700: sptr = (unsigned short *) &scores[i].sc_monster;
701: *sptr = ((unsigned short) *input++) & 0xff;
702: *sptr |= (((unsigned short) *input++) << 8) & 0xff00;
703:
704: sptr = (unsigned short *) &scores[i].sc_quest;
705: *sptr = ((unsigned short) *input++) & 0xff;
706: *sptr |= (((unsigned short) *input++) << 8) & 0xff00;
707:
708: /* Finally comes the char fields -- they're easy */
709: cptr = (unsigned char *) scores[i].sc_name;
710: for (j = 0; j < NAMELEN; j++) *cptr++ = *input++;
711:
712: cptr = (unsigned char *) scores[i].sc_system;
713: for (j = 0; j < SYSLEN; j++) *cptr++ = *input++;
714:
715: cptr = (unsigned char *) scores[i].sc_login;
716: for (j = 0; j < LOGLEN; j++) *cptr++ = *input++;
717: }
718: }
719:
720: /*
721: * scoreout:
722: * Convert a score file structure to a character string. We do
723: * this for compatibility sake since some machines write out fields in
724: * different orders.
725: */
726: void
727: scoreout(struct sc_ent scores[], unsigned char *output)
728: {
729: register int i, j;
730: unsigned long *lptr;
731: unsigned short *sptr;
732: unsigned char *cptr;
733:
734: for (i=0; i<NUMSCORE; i++) {
735: /* The long fields are first -- ordered low to high byte in input */
736: lptr = &scores[i].sc_score;
737: for (j = 0; j < sizeof(unsigned long); j++)
738: *output++ = (unsigned char) ((*lptr >> 8*j) & 0xff);
739:
740: /* The short fields are next -- ordered low to high byte in input */
741: sptr = (unsigned short *) &scores[i].sc_flags;
742: *output++ = (unsigned char) (*sptr & 0xff);
743: *output++ = (unsigned char) ((*sptr >> 8) & 0xff);
744:
745: sptr = (unsigned short *) &scores[i].sc_level;
746: *output++ = (unsigned char) (*sptr & 0xff);
747: *output++ = (unsigned char) ((*sptr >> 8) & 0xff);
748:
749: sptr = (unsigned short *) &scores[i].sc_ctype;
750: *output++ = (unsigned char) (*sptr & 0xff);
751: *output++ = (unsigned char) ((*sptr >> 8) & 0xff);
752:
753: sptr = (unsigned short *) &scores[i].sc_monster;
754: *output++ = (unsigned char) (*sptr & 0xff);
755: *output++ = (unsigned char) ((*sptr >> 8) & 0xff);
756:
757: sptr = (unsigned short *) &scores[i].sc_quest;
758: *output++ = (unsigned char) (*sptr & 0xff);
759: *output++ = (unsigned char) ((*sptr >> 8) & 0xff);
760:
761: /* Finally comes the char fields -- they're easy */
762: cptr = (unsigned char *) scores[i].sc_name;
763: for (j = 0; j < NAMELEN; j++) *output++ = *cptr++;
764:
765: cptr = (unsigned char *) scores[i].sc_system;
766: for (j = 0; j < SYSLEN; j++) *output++ = *cptr++;
767:
768: cptr = (unsigned char *) scores[i].sc_login;
769: for (j = 0; j < LOGLEN; j++) *output++ = *cptr++;
770: }
771: }
772:
773: /*
774: * showpack:
775: * Display the contents of the hero's pack
776: */
777: void
778: showpack(char *howso)
779: {
780: reg char *iname;
781: reg int cnt, packnum;
782: reg struct linked_list *item;
783: reg struct object *obj;
784:
785: idenpack();
786: cnt = 1;
787: clear();
788: mvprintw(0, 0, "Contents of your pack %s:\n",howso);
789: packnum = 'a';
790: for (item = pack; item != NULL; item = next(item)) {
791: obj = OBJPTR(item);
792: iname = inv_name(obj, FALSE);
793: mvprintw(cnt, 0, "%c) %s\n",packnum++,iname);
794: if (++cnt >= lines - 2 &&
795: next(item) != NULL) {
796: cnt = 1;
797: mvaddstr(lines - 1, 0, morestr);
798: refresh();
799: wait_for(' ');
800: clear();
801: }
802: }
803: mvprintw(cnt + 1,0,"--- %d Gold Pieces ---",purse);
804: refresh();
805: }
806:
807: void
808: total_winner(void)
809: {
810: register struct linked_list *item;
811: register struct object *obj;
812: register int worth;
813: register char c;
814: register int oldpurse;
815:
816: clear();
817: standout();
818: addstr(" \n");
819: addstr(" @ @ @ @ @ @@@ @ @ \n");
820: addstr(" @ @ @@ @@ @ @ @ @ \n");
821: addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
822: addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
823: addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
824: addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
825: addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
826: addstr(" \n");
827: addstr(" Congratulations, you have made it to the light of day! \n");
828: standend();
829: addstr("\nYou have joined the elite ranks of those who have escaped the\n");
830: addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
831: addstr("a great profit and are appointed leader of a ");
832: switch (player.t_ctype) {
833: case C_MAGICIAN:addstr("magician's guild.\n");
834: when C_FIGHTER: addstr("fighter's guild.\n");
835: when C_RANGER: addstr("ranger's guild.\n");
836: when C_CLERIC: addstr("monastery.\n");
837: when C_PALADIN: addstr("monastery.\n");
838: when C_MONK: addstr("monastery.\n");
839: when C_DRUID: addstr("monastery.\n");
840: when C_THIEF: addstr("thief's guild.\n");
841: when C_ASSASIN: addstr("assassin's guild.\n");
842: otherwise: addstr("tavern.\n");
843: }
844: mvaddstr(lines - 1, 0, spacemsg);
845: refresh();
846: wait_for(' ');
847: clear();
848: mvaddstr(0, 0, " Worth Item");
849: oldpurse = purse;
850: for (c = 'a', item = pack; item != NULL; c++, item = next(item))
851: {
852: obj = OBJPTR(item);
853: worth = get_worth(obj);
854: if (obj->o_group == 0)
855: worth *= obj->o_count;
856: whatis(item);
857: mvprintw(c - 'a' + 1, 0, "%c) %6d %s", c, worth, inv_name(obj, FALSE));
858: purse += worth;
859: }
860: mvprintw(c - 'a' + 1, 0," %5d Gold Pieces ", oldpurse);
861: refresh();
862: writelog(pstats.s_exp + (long) purse, WINNER, '\0');
863: score(pstats.s_exp + (long) purse, WINNER, '\0');
864: endwin();
865: #ifdef PC7300
866: endhardwin();
867: #endif
868: exit(0);
869: }
870:
871: int
872: update(struct sc_ent top_ten[], unsigned long amount, short quest, char *whoami,
873: short flags, short level, short monst, short ctype, char *system,
874: char *login)
875: {
876: register struct sc_ent *scp, *sc2;
877: int retval=0; /* 1 if a change, 0 otherwise */
878:
879: for (scp = top_ten; scp < &top_ten[NUMSCORE]; scp++) {
880: if (amount >= scp->sc_score)
881: break;
882:
883: #ifdef LIMITSCORE /* Limits player to one entry per class per uid */
884: /* If this good score is the same class and uid, then forget it */
885: if (strncmp(scp->sc_login, login, LOGLEN) == 0 &&
886: scp->sc_ctype == ctype &&
887: strncmp(scp->sc_system, system, SYSLEN) == 0) return(0);
888: #endif
889: }
890:
891: if (scp < &top_ten[NUMSCORE])
892: {
893: retval = 1;
894:
895: #ifdef LIMITSCORE /* Limits player to one entry per class per uid */
896: /* If a lower scores exists for the same login and class, delete it */
897: for (sc2 = scp ;sc2 < &top_ten[NUMSCORE]; sc2++) {
898: if (sc2->sc_score == 0L) break; /* End of useful scores */
899:
900: if (strncmp(sc2->sc_login, login, LOGLEN) == 0 &&
901: sc2->sc_ctype == ctype &&
902: strncmp(sc2->sc_system, system, SYSLEN) == 0) {
903: /* We want to delete this entry */
904: while (sc2 < &top_ten[NUMSCORE-1]) {
905: *sc2 = *(sc2+1);
906: sc2++;
907: }
908: sc2->sc_score = 0L;
909: }
910: }
911: #endif
912:
913: for (sc2 = &top_ten[NUMSCORE-1]; sc2 > scp; sc2--)
914: *sc2 = *(sc2-1);
915: scp->sc_score = amount;
916: scp->sc_quest = quest;
917: strncpy(scp->sc_name, whoami, NAMELEN);
918: scp->sc_flags = flags;
919: scp->sc_level = level;
920: scp->sc_monster = monst;
921: scp->sc_ctype = ctype;
922: strncpy(scp->sc_system, system, SYSLEN);
923: strncpy(scp->sc_login, login, LOGLEN);
924: }
925:
926: return(retval);
927: }
CVSweb