Mercurial > hg > early-roguelike
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 } |