Mercurial > hg > early-roguelike
comparison xrogue/rip.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 21 Apr 2015 08:55:20 -0400 |
parents | |
children | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 133:e6179860cb76 |
---|---|
1 /* | |
2 rip.c - File for the fun ends Death or a total win | |
3 | |
4 XRogue: Expeditions into the Dungeons of Doom | |
5 Copyright (C) 1991 Robert Pietkivitch | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
10 All rights reserved. | |
11 | |
12 Based on "Rogue: Exploring the Dungeons of Doom" | |
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
14 All rights reserved. | |
15 | |
16 See the file LICENSE.TXT for full copyright and licensing information. | |
17 */ | |
18 | |
19 #define REALLIFE 1 /* Print out machine and logname */ | |
20 #define EDITSCORE 2 /* Edit the current score file */ | |
21 #define ADDSCORE 3 /* Add a new score */ | |
22 | |
23 #include <curses.h> | |
24 #include <time.h> | |
25 #include <signal.h> | |
26 #include <ctype.h> | |
27 #include <sys/types.h> | |
28 #include <fcntl.h> | |
29 #include "mach_dep.h" | |
30 #include "network.h" | |
31 #include "rogue.h" | |
32 | |
33 /* Network machines (for mutual score keeping) */ | |
34 struct network Network[] = { | |
35 { "", "" }, | |
36 }; | |
37 | |
38 static char *rip[] = { | |
39 " ___________", | |
40 " / \\", | |
41 " / \\", | |
42 " / R. I. P. \\", | |
43 " / \\", | |
44 " / \\", | |
45 " | |", | |
46 " | |", | |
47 " | killed by |", | |
48 " | |", | |
49 " | |", | |
50 " | |", | |
51 " *| * * * |*", | |
52 " _________)|//\\\\///\\///\\//\\//\\/|(_________", | |
53 NULL | |
54 }; | |
55 | |
56 char *killname(); | |
57 | |
58 /*UNUSED*/ | |
59 void | |
60 byebye(sig) | |
61 int sig; | |
62 { | |
63 NOOP(sig); | |
64 exit_game(EXIT_ENDWIN); | |
65 } | |
66 | |
67 | |
68 /* | |
69 * death: | |
70 * Do something really fun when he dies | |
71 */ | |
72 | |
73 death(monst) | |
74 register short monst; | |
75 { | |
76 register char **dp = rip, *killer; | |
77 register struct tm *lt; | |
78 time_t date; | |
79 char buf[LINELEN]; | |
80 struct tm *localtime(); | |
81 | |
82 time(&date); | |
83 lt = localtime(&date); | |
84 clear(); | |
85 move(8, 0); | |
86 while (*dp) | |
87 printw("%s\n", *dp++); | |
88 mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami); | |
89 sprintf(buf, "%lu Points", pstats.s_exp ); | |
90 mvaddstr(15, 28-((strlen(buf)+1)/2), buf); | |
91 killer = killname(monst); | |
92 mvaddstr(17, 28-((strlen(killer)+1)/2), killer); | |
93 mvaddstr(18, 25, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf)); | |
94 move(lines-1, 0); | |
95 refresh(); | |
96 score(pstats.s_exp, KILLED, monst); | |
97 exit_game(EXIT_ENDWIN); | |
98 } | |
99 | |
100 char * | |
101 killname(monst) | |
102 register short monst; | |
103 { | |
104 static char mons_name[LINELEN/2]; | |
105 int i; | |
106 | |
107 if (monst > NUMMONST) return("a strange monster"); | |
108 | |
109 if (monst >= 0) { | |
110 switch (monsters[monst].m_name[0]) { | |
111 case 'a': | |
112 case 'e': | |
113 case 'i': | |
114 case 'o': | |
115 case 'u': | |
116 sprintf(mons_name, "an %s", monsters[monst].m_name); | |
117 break; | |
118 default: | |
119 sprintf(mons_name, "a %s", monsters[monst].m_name); | |
120 } | |
121 return(mons_name); | |
122 } | |
123 for (i = 0; i< DEATHNUM; i++) { | |
124 if (deaths[i].reason == monst) | |
125 break; | |
126 } | |
127 if (i >= DEATHNUM) | |
128 return ("strange death"); | |
129 return (deaths[i].name); | |
130 } | |
131 | |
132 /* | |
133 * score -- figure score and post it. | |
134 */ | |
135 | |
136 /* VARARGS2 */ | |
137 score(amount, flags, monst) | |
138 unsigned long amount; | |
139 int flags; | |
140 short monst; | |
141 { | |
142 struct sc_ent top_ten[NUMSCORE]; | |
143 register struct sc_ent *scp; | |
144 register int i; | |
145 register struct sc_ent *sc2; | |
146 register FILE *outf; | |
147 register char *killer; | |
148 register int prflags = 0; | |
149 short upquest=0, wintype=0, uplevel=0, uptype=0; /* For network updating */ | |
150 char upsystem[SYSLEN], uplogin[LOGLEN]; | |
151 char *thissys; /* Holds the name of this system */ | |
152 | |
153 #define REASONLEN 3 | |
154 static char *reason[] = { | |
155 "killed", | |
156 "quit", | |
157 "A total winner", | |
158 "somehow left", | |
159 }; | |
160 char *packend; | |
161 | |
162 memset(top_ten,0,sizeof(top_ten)); | |
163 | |
164 signal(SIGINT, byebye); | |
165 if (level == 0 && max_level == 0) | |
166 amount = 0; /*don't count if quit early */ | |
167 if (flags != WINNER && flags != SCOREIT && flags != UPDATE) { | |
168 if (flags == CHICKEN) { | |
169 packend = "when you quit"; | |
170 amount = amount / 100; | |
171 } | |
172 else | |
173 packend = "at your untimely demise"; | |
174 mvaddstr(lines - 1, 0, retstr); | |
175 refresh(); | |
176 getstr(prbuf); | |
177 showpack(packend); | |
178 } | |
179 purse = 0; /* Steal all the gold */ | |
180 | |
181 /* | |
182 * Open file and read list | |
183 */ | |
184 | |
185 if ((outf = fopen(score_file, "rb+")) == NULL) | |
186 { | |
187 if ((outf = fopen(score_file, "wb+")) == NULL) | |
188 { | |
189 mvprintw(lines - 1, 0, "Unable to open or create score file: %s",score_file); | |
190 refresh(); | |
191 return; | |
192 } | |
193 } | |
194 | |
195 thissys = md_gethostname(); | |
196 | |
197 /* | |
198 * If this is a SCOREIT optin (rogue -s), don't call byebye. The | |
199 * endwin() calls in byebye() will and this results in a core dump. | |
200 */ | |
201 if (flags == SCOREIT) signal(SIGINT, SIG_DFL); | |
202 else signal(SIGINT, byebye); | |
203 | |
204 if (flags != SCOREIT && flags != UPDATE) | |
205 { | |
206 mvaddstr(lines - 1, 0, retstr); | |
207 refresh(); | |
208 fflush(stdout); | |
209 getstr(prbuf); | |
210 } | |
211 | |
212 /* Check for special options */ | |
213 if (strcmp(prbuf, "names") == 0) | |
214 prflags = REALLIFE; | |
215 else if (wizard) { | |
216 if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE; | |
217 else if (strcmp(prbuf, "add") == 0) { | |
218 prflags = ADDSCORE; | |
219 waswizard = FALSE; /* We want the new score recorded */ | |
220 } | |
221 } | |
222 | |
223 /* Read the score and convert it to a compatible format */ | |
224 | |
225 fseek(outf, 0, SEEK_SET); | |
226 rs_read_scorefile(outf, top_ten, NUMSCORE); | |
227 | |
228 /* Get some values if this is an update */ | |
229 if (flags == UPDATE) { | |
230 int errcheck, errors = 0; | |
231 | |
232 upquest = (short) netread(&errcheck, sizeof(short), stdin); | |
233 if (errcheck) errors++; | |
234 | |
235 if (fread(whoami, 1, NAMELEN, stdin) != NAMELEN) errors++; | |
236 | |
237 wintype = (short) netread(&errcheck, sizeof(short), stdin); | |
238 if (errcheck) errors++; | |
239 | |
240 uplevel = (short) netread(&errcheck, sizeof(short), stdin); | |
241 if (errcheck) errors++; | |
242 | |
243 uptype = (short) netread(&errcheck, sizeof(short), stdin); | |
244 if (errcheck) errors++; | |
245 | |
246 if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN) | |
247 errors++; | |
248 if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN) | |
249 errors++; | |
250 | |
251 if (errors) { | |
252 fclose(outf); | |
253 return; | |
254 } | |
255 } | |
256 | |
257 /* | |
258 * Insert player in list if need be | |
259 */ | |
260 if (!waswizard) { | |
261 char *login= NULL; | |
262 | |
263 if (flags != UPDATE) { | |
264 login = md_getusername(); | |
265 | |
266 if ((login == NULL) || (*login == 0)) | |
267 login = "another rogue fiend"; | |
268 } | |
269 | |
270 if (flags == UPDATE) | |
271 (void) update(top_ten, amount, upquest, whoami, wintype, | |
272 uplevel, monst, uptype, upsystem, uplogin); | |
273 else { | |
274 if (prflags == ADDSCORE) { /* Overlay characteristic by new ones */ | |
275 char buffer[LINELEN]; | |
276 | |
277 clear(); | |
278 mvaddstr(1, 0, "Score: "); | |
279 mvaddstr(2, 0, "Quest (number): "); | |
280 mvaddstr(3, 0, "Name: "); | |
281 mvaddstr(4, 0, "System: "); | |
282 mvaddstr(5, 0, "Login: "); | |
283 mvaddstr(6, 0, "Level: "); | |
284 mvaddstr(7, 0, "Char type: "); | |
285 mvaddstr(8, 0, "Result: "); | |
286 | |
287 /* Get the score */ | |
288 move(1, 7); | |
289 get_str(buffer, stdscr); | |
290 amount = atol(buffer); | |
291 | |
292 /* Get the character's quest -- must be a number */ | |
293 move(2, 16); | |
294 get_str(buffer, stdscr); | |
295 quest_item = atoi(buffer); | |
296 | |
297 /* Get the character's name */ | |
298 move(3, 6); | |
299 get_str(buffer, stdscr); | |
300 strncpy(whoami, buffer, NAMELEN); | |
301 | |
302 /* Get the system */ | |
303 move(4, 8); | |
304 get_str(buffer, stdscr); | |
305 strncpy(thissys, buffer, SYSLEN); | |
306 | |
307 /* Get the login */ | |
308 move(5, 7); | |
309 get_str(buffer, stdscr); | |
310 strncpy(login, buffer, LOGLEN); | |
311 | |
312 /* Get the level */ | |
313 move(6, 7); | |
314 get_str(buffer, stdscr); | |
315 level = max_level = (short) atoi(buffer); | |
316 | |
317 /* Get the character type */ | |
318 move(7, 11); | |
319 get_str(buffer, stdscr); | |
320 for (i=0; i<NUM_CHARTYPES; i++) { | |
321 if (EQSTR(buffer, char_class[i].name, strlen(buffer))) | |
322 break; | |
323 } | |
324 player.t_ctype = i; | |
325 | |
326 /* Get the win type */ | |
327 move(8, 8); | |
328 get_str(buffer, stdscr); | |
329 switch (buffer[0]) { | |
330 case 'W': | |
331 case 'w': | |
332 case 'T': | |
333 case 't': | |
334 flags = WINNER; | |
335 break; | |
336 | |
337 case 'Q': | |
338 case 'q': | |
339 flags = CHICKEN; | |
340 break; | |
341 | |
342 case 'k': | |
343 case 'K': | |
344 default: | |
345 flags = KILLED; | |
346 break; | |
347 } | |
348 | |
349 /* Get the monster if player was killed */ | |
350 if (flags == KILLED) { | |
351 mvaddstr(9, 0, "Death type: "); | |
352 get_str(buffer, stdscr); | |
353 if (buffer[0] == 'M' || buffer[0] == 'm') | |
354 do { | |
355 monst = makemonster(TRUE, "choose"); | |
356 } while (monst < 0); /* Force a choice */ | |
357 else monst = getdeath(); | |
358 } | |
359 } | |
360 | |
361 if (update(top_ten, amount, (short) quest_item, whoami, flags, | |
362 (flags == WINNER) ? (short) max_level : (short) level, | |
363 monst, player.t_ctype, thissys, login) | |
364 ) { | |
365 /* Send this update to the other systems in the network */ | |
366 int i, j; | |
367 char cmd[256]; /* Command for remote execution */ | |
368 FILE *rmf, *popen(); /* For input to remote command */ | |
369 | |
370 for (i=0; Network[i].system[0] != 0; i++) | |
371 if (Network[i].system[0] != '!' && | |
372 strcmp(Network[i].system, thissys)) { | |
373 sprintf(cmd, NETCOMMAND, | |
374 Network[i].system, Network[i].rogue); | |
375 | |
376 /* Execute the command */ | |
377 if ((rmf=popen(cmd, "w")) != NULL) { | |
378 unsigned long temp; /* Temporary value */ | |
379 | |
380 /* Write out the parameters */ | |
381 (void) netwrite((unsigned long) amount, | |
382 sizeof(unsigned long), rmf); | |
383 | |
384 (void) netwrite((unsigned long) monst, | |
385 sizeof(short), rmf); | |
386 | |
387 (void) netwrite((unsigned long) quest_item, | |
388 sizeof(short), rmf); | |
389 | |
390 (void) fwrite(whoami, 1, strlen(whoami), rmf); | |
391 for (j=strlen(whoami); j<NAMELEN; j++) | |
392 putc('\0', rmf); | |
393 | |
394 (void) netwrite((unsigned long) flags, | |
395 sizeof(short), rmf); | |
396 | |
397 temp = (unsigned long) | |
398 (flags==WINNER ? max_level : level); | |
399 (void) netwrite(temp, sizeof(short), rmf); | |
400 | |
401 (void) netwrite((unsigned long) player.t_ctype, | |
402 sizeof(short), rmf); | |
403 | |
404 (void) fwrite(thissys, 1, | |
405 strlen(thissys), rmf); | |
406 for (j=strlen(thissys); j<SYSLEN; j++) | |
407 putc('\0', rmf); | |
408 | |
409 (void) fwrite(login, 1, strlen(login), rmf); | |
410 for (j=strlen(login); j<LOGLEN; j++) | |
411 putc('\0', rmf); | |
412 | |
413 /* Close off the command */ | |
414 (void) pclose(rmf); | |
415 } | |
416 } | |
417 } | |
418 } | |
419 } | |
420 | |
421 /* | |
422 * SCOREIT -- rogue -s option. Never started curses if this option. | |
423 * UPDATE -- network scoring update. Never started curses if this option. | |
424 * EDITSCORE -- want to delete or change a score. | |
425 */ | |
426 /* if (flags != SCOREIT && flags != UPDATE && prflags != EDITSCORE) | |
427 endwin(); */ | |
428 | |
429 if (flags != UPDATE) { | |
430 if (flags != SCOREIT) { | |
431 clear(); | |
432 refresh(); | |
433 endwin(); | |
434 } | |
435 /* | |
436 * Print the list | |
437 */ | |
438 printf("\nTop %d Adventurers:\nRank Score\tName\n", | |
439 NUMSCORE); | |
440 for (scp = top_ten; scp < &top_ten[NUMSCORE]; scp++) { | |
441 char *class; | |
442 | |
443 if (scp->sc_score != 0) { | |
444 class = char_class[scp->sc_ctype].name; | |
445 | |
446 /* Make sure we have an in-bound reason */ | |
447 if (scp->sc_flags > REASONLEN) scp->sc_flags = REASONLEN; | |
448 | |
449 printf("%3d %10lu\t%s (%s)", scp - top_ten + 1, | |
450 scp->sc_score, scp->sc_name, class); | |
451 | |
452 if (prflags == REALLIFE) printf(" [in real life %.*s!%.*s]", | |
453 SYSLEN, scp->sc_system, LOGLEN, scp->sc_login); | |
454 | |
455 printf(":\n\t\t%s on level %d", reason[scp->sc_flags], | |
456 scp->sc_level); | |
457 | |
458 switch (scp->sc_flags) { | |
459 case KILLED: | |
460 printf(" by"); | |
461 killer = killname(scp->sc_monster); | |
462 printf(" %s", killer); | |
463 break; | |
464 | |
465 case WINNER: | |
466 printf(" with the %s", | |
467 rel_magic[scp->sc_quest].mi_name); | |
468 break; | |
469 } | |
470 | |
471 if (prflags == EDITSCORE) | |
472 { | |
473 fflush(stdout); | |
474 getstr(prbuf); | |
475 printf("\n"); | |
476 if (prbuf[0] == 'd') { | |
477 for (sc2 = scp; sc2 < &top_ten[NUMSCORE-1]; sc2++) | |
478 *sc2 = *(sc2 + 1); | |
479 top_ten[NUMSCORE-1].sc_score = 0; | |
480 for (i = 0; i < NAMELEN; i++) | |
481 top_ten[NUMSCORE-1].sc_name[i] = rnd(255); | |
482 top_ten[NUMSCORE-1].sc_flags = RN; | |
483 top_ten[NUMSCORE-1].sc_level = RN; | |
484 top_ten[NUMSCORE-1].sc_monster = RN; | |
485 scp--; | |
486 } | |
487 else if (prbuf[0] == 'e') { | |
488 printf("Death type: "); | |
489 getstr(prbuf); | |
490 if (prbuf[0] == 'M' || prbuf[0] == 'm') | |
491 do { | |
492 scp->sc_monster = | |
493 makemonster(TRUE, "choose"); | |
494 } while (scp->sc_monster < 0); /* Force a choice */ | |
495 else scp->sc_monster = getdeath(); | |
496 clear(); | |
497 refresh(); | |
498 } | |
499 } | |
500 else printf("\n"); | |
501 } | |
502 } | |
503 /* if (prflags == EDITSCORE) endwin();*/ /* End editing windowing */ | |
504 } | |
505 fseek(outf, 0L, SEEK_SET); | |
506 | |
507 if (flags != SCOREIT) | |
508 rs_write_scorefile(outf,top_ten,NUMSCORE); | |
509 fclose(outf); | |
510 } | |
511 | |
512 /* | |
513 * showpack: | |
514 * Display the contents of the hero's pack | |
515 */ | |
516 | |
517 showpack(howso) | |
518 char *howso; | |
519 { | |
520 reg char *iname; | |
521 reg int cnt, packnum; | |
522 reg struct linked_list *item; | |
523 reg struct object *obj; | |
524 | |
525 idenpack(); | |
526 cnt = 1; | |
527 clear(); | |
528 mvprintw(0, 0, "Contents of your pack %s:\n",howso); | |
529 packnum = 'a'; | |
530 for (item = pack; item != NULL; item = next(item)) { | |
531 obj = OBJPTR(item); | |
532 iname = inv_name(obj, FALSE); | |
533 mvprintw(cnt, 0, "%c) %s\n",packnum++,iname); | |
534 if (++cnt >= lines - 2 && | |
535 next(item) != NULL) { | |
536 cnt = 1; | |
537 mvaddstr(lines - 1, 0, morestr); | |
538 refresh(); | |
539 wait_for(' '); | |
540 clear(); | |
541 } | |
542 } | |
543 mvprintw(cnt + 1,0,"--- %ld Gold Pieces ---",purse); | |
544 refresh(); | |
545 } | |
546 | |
547 total_winner() | |
548 { | |
549 register struct linked_list *item; | |
550 register struct object *obj; | |
551 register long worth; | |
552 register char c; | |
553 register long oldpurse; | |
554 | |
555 clear(); | |
556 standout(); | |
557 addstr(" \n"); | |
558 addstr(" @ @ @ @ @ @@@ @ @ \n"); | |
559 addstr(" @ @ @@ @@ @ @ @ @ \n"); | |
560 addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n"); | |
561 addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n"); | |
562 addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n"); | |
563 addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n"); | |
564 addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n"); | |
565 addstr(" \n"); | |
566 addstr(" Congratulations, you have made it to the light of day! \n"); | |
567 standend(); | |
568 addstr("\nYou have joined the elite ranks of those who have escaped the\n"); | |
569 addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n"); | |
570 addstr("a great profit and are appointed "); | |
571 switch (player.t_ctype) { | |
572 case C_FIGHTER: addstr("Leader of the Fighter's Guild.\n"); | |
573 when C_RANGER: addstr("King of the Northern Land.\n"); | |
574 when C_PALADIN: addstr("King of the Southern Land.\n"); | |
575 when C_MAGICIAN:addstr("High Wizard of the Sorcerer's Guild.\n"); | |
576 when C_CLERIC: addstr("Bishop of the Monastery.\n"); | |
577 when C_THIEF: addstr("Leader of the Thief's Guild.\n"); | |
578 when C_MONK: addstr("Master of the Temple.\n"); | |
579 when C_ASSASSIN: addstr("Leader of the Assassin's Guild.\n"); | |
580 when C_DRUID: addstr("High Priest of the Monastery.\n"); | |
581 otherwise: addstr("Town Drunk in the Tavern.\n"); | |
582 } | |
583 mvaddstr(lines - 1, 0, spacemsg); | |
584 refresh(); | |
585 wait_for(' '); | |
586 clear(); | |
587 mvaddstr(0, 0, " Worth Item"); | |
588 oldpurse = purse; | |
589 for (c = 'a', item = pack; item != NULL; c++, item = next(item)) | |
590 { | |
591 obj = OBJPTR(item); | |
592 worth = get_worth(obj); | |
593 if (obj->o_group == 0) | |
594 worth *= obj->o_count; | |
595 whatis(item); | |
596 mvprintw(c-'a'+1, 0, "%c) %6ld %s", c, worth, inv_name(obj, FALSE)); | |
597 purse += worth; | |
598 } | |
599 mvprintw(c - 'a' + 1, 0," %5ld Gold Pieces ", oldpurse); | |
600 refresh(); | |
601 score(pstats.s_exp + (long) purse, WINNER, '\0'); | |
602 exit_game(EXIT_ENDWIN); | |
603 } | |
604 | |
605 | |
606 void | |
607 delete_score(top_ten, idx) | |
608 struct sc_ent top_ten[NUMSCORE]; | |
609 int idx; | |
610 { | |
611 for(;idx < NUMSCORE-1;idx++) | |
612 top_ten[idx] = top_ten[idx+1]; | |
613 | |
614 top_ten[NUMSCORE-1].sc_score = 0L; | |
615 } | |
616 | |
617 int | |
618 insert_score(top_ten, sc) | |
619 struct sc_ent top_ten[NUMSCORE]; | |
620 struct sc_ent *sc; | |
621 { | |
622 int i,j; | |
623 | |
624 if (top_ten[NUMSCORE-1].sc_score > 0) | |
625 return(-1); /* no room */ | |
626 | |
627 for(i = 0; i < NUMSCORE; i++) { | |
628 if (sc->sc_score > top_ten[i].sc_score) { | |
629 for(j = NUMSCORE-1; j > i; j--) | |
630 top_ten[j] = top_ten[j-1]; | |
631 top_ten[i] = *sc; | |
632 return(i); | |
633 } | |
634 } | |
635 | |
636 return(-1); | |
637 } | |
638 | |
639 /* PCS = player-class-system (used to determines uniqueness of player) */ | |
640 | |
641 int | |
642 is_pcs_match(sc1,sc2) | |
643 struct sc_ent *sc1; | |
644 struct sc_ent *sc2; | |
645 { | |
646 return( (strcmp(sc1->sc_name,sc2->sc_name) == 0) && | |
647 (sc1->sc_ctype == sc2->sc_ctype) && | |
648 (strcmp(sc1->sc_system, sc2->sc_system)==0) ); | |
649 } | |
650 | |
651 int | |
652 count_pcs_matches(top_ten,sc,lowest) | |
653 struct sc_ent top_ten[NUMSCORE]; | |
654 struct sc_ent *sc; | |
655 int *lowest; | |
656 { | |
657 int i, matches = 0; | |
658 | |
659 *lowest = -1; | |
660 | |
661 for(i = 0; i < NUMSCORE; i++) { | |
662 if (is_pcs_match(sc,&top_ten[i])) { | |
663 matches++; | |
664 *lowest = i; | |
665 } | |
666 } | |
667 return(matches); | |
668 } | |
669 | |
670 int | |
671 find_most_pcs_matches(top_ten,sc,num,idx) | |
672 struct sc_ent top_ten[NUMSCORE]; | |
673 struct sc_ent *sc; | |
674 int *num, *idx; | |
675 { | |
676 int i, matches, max_match=0, max_match_idx=-1, lowest; | |
677 | |
678 for(i = NUMSCORE-1; i > 0; i--) { | |
679 matches = count_pcs_matches(top_ten,&top_ten[i],&lowest); | |
680 | |
681 if (matches > max_match) { | |
682 max_match = matches; | |
683 max_match_idx = lowest; | |
684 } | |
685 } | |
686 | |
687 matches = count_pcs_matches(top_ten,sc,&lowest) + 1; | |
688 | |
689 if (matches > max_match) { | |
690 *num = matches; | |
691 *idx = lowest; | |
692 } | |
693 else { | |
694 *num = max_match; | |
695 *idx = max_match_idx; | |
696 } | |
697 | |
698 return(0); | |
699 } | |
700 | |
701 | |
702 int | |
703 add_score(top_ten,sc) | |
704 struct sc_ent top_ten[NUMSCORE]; | |
705 struct sc_ent *sc; | |
706 { | |
707 int idx, count; | |
708 | |
709 if (insert_score(top_ten,sc) == -1) { | |
710 /* Simple insert if space available in table */ | |
711 | |
712 find_most_pcs_matches(top_ten,sc,&count,&idx); | |
713 | |
714 /* EVERY ENTRY UNIQUE, */ | |
715 /* INSERT IF SCORE > LOWEST MATCH SCORE */ | |
716 if (count == 1) { | |
717 if (sc->sc_score > top_ten[idx].sc_score) { | |
718 delete_score(top_ten,idx); | |
719 insert_score(top_ten,sc); | |
720 } | |
721 } | |
722 /* CURRENT PCS HAS HIGHEST DUPE COUNT */ | |
723 /* INSERT IF SCORE > LOWEST MATCH SCORE */ | |
724 else if (is_pcs_match(sc,&top_ten[idx])) { | |
725 if (sc->sc_score > top_ten[idx].sc_score) { | |
726 delete_score(top_ten,idx); | |
727 insert_score(top_ten,sc); | |
728 } | |
729 } | |
730 /* UNRELATED PCS HAS HIGHEST DUPE COUNT */ | |
731 /* DELETE LOWEST DUPE TO MAKE ROOM AND INSERT */ | |
732 else { | |
733 delete_score(top_ten,idx); | |
734 insert_score(top_ten,sc); | |
735 } | |
736 } | |
737 } | |
738 | |
739 update(top_ten, amount, quest, whoami, flags, level, monst, ctype, system, login) | |
740 struct sc_ent top_ten[]; | |
741 unsigned long amount; | |
742 short quest, flags, level, monst, ctype; | |
743 char *whoami, *system, *login; | |
744 { | |
745 struct sc_ent sc; | |
746 | |
747 sc.sc_score = amount; | |
748 sc.sc_quest = quest; | |
749 strncpy(sc.sc_name, whoami, NAMELEN); | |
750 sc.sc_name[NAMELEN-1] = 0; | |
751 sc.sc_flags = flags; | |
752 sc.sc_level = level; | |
753 sc.sc_monster = monst; | |
754 sc.sc_ctype = ctype; | |
755 strncpy(sc.sc_system, system, SYSLEN); | |
756 sc.sc_system[SYSLEN - 1] = 0; | |
757 strncpy(sc.sc_login, login, LOGLEN); | |
758 sc.sc_login[LOGLEN-1] = 0; | |
759 | |
760 add_score(top_ten, &sc); | |
761 return(1); | |
762 } | |
763 |