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