OSDN Git Service

60c741a6ceeb64bd7293f2c82791c0101b3629d5
[hengband/hengband.git] / src / scores.c
1 /* File: scores.c */
2
3 /* Purpose: Highscores handling */
4
5 /*
6  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research, and
9  * not for profit purposes provided that this copyright and statement are
10  * included in all such copies.
11  */
12
13 #include "angband.h"
14
15
16 /*
17  * Seek score 'i' in the highscore file
18  */
19 static int highscore_seek(int i)
20 {
21         /* Seek for the requested record */
22         return (fd_seek(highscore_fd, (huge)(i) * sizeof(high_score)));
23 }
24
25
26 /*
27  * Read one score from the highscore file
28  */
29 static errr highscore_read(high_score *score)
30 {
31         /* Read the record, note failure */
32         return (fd_read(highscore_fd, (char*)(score), sizeof(high_score)));
33 }
34
35
36 /*
37  * Write one score to the highscore file
38  */
39 static int highscore_write(high_score *score)
40 {
41         /* Write the record, note failure */
42         return (fd_write(highscore_fd, (char*)(score), sizeof(high_score)));
43 }
44
45
46 /*
47  * Just determine where a new score *would* be placed
48  * Return the location (0 is best) or -1 on failure
49  */
50 static int highscore_where(high_score *score)
51 {
52         int                     i;
53
54         high_score              the_score;
55         int my_score;
56
57         my_score = atoi(score->pts);
58
59         /* Paranoia -- it may not have opened */
60         if (highscore_fd < 0) return (-1);
61
62         /* Go to the start of the highscore file */
63         if (highscore_seek(0)) return (-1);
64
65         /* Read until we get to a higher score */
66         for (i = 0; i < MAX_HISCORES; i++)
67         {
68                 int old_score;
69                 if (highscore_read(&the_score)) return (i);
70                 old_score = atoi(the_score.pts);
71 /*              if (strcmp(the_score.pts, score->pts) < 0) return (i); */
72                 if (my_score > old_score) return (i);
73         }
74
75         /* The "last" entry is always usable */
76         return (MAX_HISCORES - 1);
77 }
78
79
80 /*
81  * Actually place an entry into the high score file
82  * Return the location (0 is best) or -1 on "failure"
83  */
84 static int highscore_add(high_score *score)
85 {
86         int                     i, slot;
87         bool            done = FALSE;
88
89         high_score              the_score, tmpscore;
90
91
92         /* Paranoia -- it may not have opened */
93         if (highscore_fd < 0) return (-1);
94
95         /* Determine where the score should go */
96         slot = highscore_where(score);
97
98         /* Hack -- Not on the list */
99         if (slot < 0) return (-1);
100
101         /* Hack -- prepare to dump the new score */
102         the_score = (*score);
103
104         /* Slide all the scores down one */
105         for (i = slot; !done && (i < MAX_HISCORES); i++)
106         {
107                 /* Read the old guy, note errors */
108                 if (highscore_seek(i)) return (-1);
109                 if (highscore_read(&tmpscore)) done = TRUE;
110
111                 /* Back up and dump the score we were holding */
112                 if (highscore_seek(i)) return (-1);
113                 if (highscore_write(&the_score)) return (-1);
114
115                 /* Hack -- Save the old score, for the next pass */
116                 the_score = tmpscore;
117         }
118
119         /* Return location used */
120         return (slot);
121 }
122
123
124
125 /*
126  * Display the scores in a given range.
127  * Assumes the high score list is already open.
128  * Only five entries per line, too much info.
129  *
130  * Mega-Hack -- allow "fake" entry at the given position.
131  */
132 void display_scores_aux(int from, int to, int note, high_score *score)
133 {
134         int             i, j, k, n, place;
135         byte attr;
136
137         high_score      the_score;
138
139         char    out_val[256];
140         char    tmp_val[160];
141
142
143         /* Paranoia -- it may not have opened */
144         if (highscore_fd < 0) return;
145
146
147         /* Assume we will show the first 10 */
148         if (from < 0) from = 0;
149         if (to < 0) to = 10;
150         if (to > MAX_HISCORES) to = MAX_HISCORES;
151
152
153         /* Seek to the beginning */
154         if (highscore_seek(0)) return;
155
156         /* Hack -- Count the high scores */
157         for (i = 0; i < MAX_HISCORES; i++)
158         {
159                 if (highscore_read(&the_score)) break;
160         }
161
162         /* Hack -- allow "fake" entry to be last */
163         if ((note == i) && score) i++;
164
165         /* Forget about the last entries */
166         if (i > to) i = to;
167
168
169         /* Show 5 per page, until "done" */
170         for (k = from, place = k+1; k < i; k += 5)
171         {
172                 /* Clear screen */
173                 Term_clear();
174
175                 /* Title */
176 #ifdef JP
177 put_str("                ÊѶòÈÚÅÜ: Í¦¼Ô¤ÎÅÂƲ", 0, 0);
178 #else
179                 put_str("                Hengband Hall of Fame", 0, 0);
180 #endif
181
182
183                 /* Indicate non-top scores */
184                 if (k > 0)
185                 {
186 #ifdef JP
187 sprintf(tmp_val, "( %d °Ì°Ê²¼ )", k + 1);
188 #else
189                         sprintf(tmp_val, "(from position %d)", k + 1);
190 #endif
191
192                         put_str(tmp_val, 0, 40);
193                 }
194
195                 /* Dump 5 entries */
196                 for (j = k, n = 0; j < i && n < 5; place++, j++, n++)
197                 {
198                         int pr, pc, pa, clev, mlev, cdun, mdun;
199
200                         cptr user, gold, when, aged;
201
202
203                         /* Hack -- indicate death in yellow */
204                         attr = (j == note) ? TERM_YELLOW : TERM_WHITE;
205
206
207                         /* Mega-Hack -- insert a "fake" record */
208                         if ((note == j) && score)
209                         {
210                                 the_score = (*score);
211                                 attr = TERM_L_GREEN;
212                                 score = NULL;
213                                 note = -1;
214                                 j--;
215                         }
216
217                         /* Read a normal record */
218                         else
219                         {
220                                 /* Read the proper record */
221                                 if (highscore_seek(j)) break;
222                                 if (highscore_read(&the_score)) break;
223                         }
224
225                         /* Extract the race/class */
226                         pr = atoi(the_score.p_r);
227                         pc = atoi(the_score.p_c);
228                         pa = atoi(the_score.p_a);
229
230                         /* Extract the level info */
231                         clev = atoi(the_score.cur_lev);
232                         mlev = atoi(the_score.max_lev);
233                         cdun = atoi(the_score.cur_dun);
234                         mdun = atoi(the_score.max_dun);
235
236                         /* Hack -- extract the gold and such */
237                         for (user = the_score.uid; isspace(*user); user++) /* loop */;
238                         for (when = the_score.day; isspace(*when); when++) /* loop */;
239                         for (gold = the_score.gold; isspace(*gold); gold++) /* loop */;
240                         for (aged = the_score.turns; isspace(*aged); aged++) /* loop */;
241
242                         /* Clean up standard encoded form of "when" */
243                         if ((*when == '@') && strlen(when) == 9)
244                         {
245                                 sprintf(tmp_val, "%.4s-%.2s-%.2s",
246                                         when + 1, when + 5, when + 7);
247                                 when = tmp_val;
248                         }
249
250                         /* Dump some info */
251 #ifdef JP
252 /*sprintf(out_val, "%3d.%9s  %s%s%s¤È¤¤¤¦Ì¾¤Î%s¤Î%s (¥ì¥Ù¥ë %d)", */
253                         sprintf(out_val, "%3d.%9s  %s%s%s - %s%s (¥ì¥Ù¥ë %d)",
254                                 place, the_score.pts,
255                                 seikaku_info[pa].title, (seikaku_info[pa].no ? "¤Î" : ""),
256                                 the_score.who,
257                                 race_info[pr].title, class_info[pc].title,
258                                 clev);
259
260 #else
261                         sprintf(out_val, "%3d.%9s  %s %s the %s %s, Level %d",
262                                 place, the_score.pts,
263                                 seikaku_info[pa].title,
264                                 the_score.who, race_info[pr].title, class_info[pc].title,
265                                 clev);
266 #endif
267
268
269                         /* Append a "maximum level" */
270 #ifdef JP
271 if (mlev > clev) strcat(out_val, format(" (ºÇ¹â%d)", mlev));
272 #else
273                         if (mlev > clev) strcat(out_val, format(" (Max %d)", mlev));
274 #endif
275
276
277                         /* Dump the first line */
278                         c_put_str(attr, out_val, n*4 + 2, 0);
279
280                         /* Another line of info */
281 #ifdef JP
282                         if (mdun != 0)
283                                 sprintf(out_val, "    ºÇ¹â%3d³¬", mdun);
284                         else
285                                 sprintf(out_val, "             ");
286
287
288                         /* »àË´¸¶°ø¤ò¥ª¥ê¥¸¥Ê¥ë¤è¤êºÙ¤«¤¯É½¼¨ */
289                         if (streq(the_score.how, "yet"))
290                         {
291                                 sprintf(out_val+13, "  ¤Þ¤ÀÀ¸¤­¤Æ¤¤¤ë (%d%s)",
292                                        cdun, "³¬");
293                         }
294                         else
295                         if (streq(the_score.how, "ripe"))
296                         {
297                           sprintf(out_val+13, "  ¾¡Íø¤Î¸å¤Ë°úÂà (%d%s)",
298                                   cdun, "³¬");
299                         }
300                         else if (streq(the_score.how, "Seppuku"))
301                         {
302                           sprintf(out_val+13, "  ¾¡Íø¤Î¸å¤ËÀÚÊ¢ (%d%s)",
303                                   cdun, "³¬");
304                         }
305                         else
306                         {
307                           /* Some people die outside of the dungeon */
308                           if (!cdun)
309                                 sprintf(out_val+13, "  ÃϾå¤Ç%s¤Ë»¦¤µ¤ì¤¿", the_score.how);
310                           else
311                               sprintf(out_val+13, "  %d³¬¤Ç%s¤Ë»¦¤µ¤ì¤¿",
312                                       cdun, the_score.how);
313                         }
314
315 #else
316                         /* Some people die outside of the dungeon */
317                         if (!cdun)
318                                 sprintf(out_val, 
319                                         "               Killed by %s on the surface",
320                                         the_score.how);
321                         else
322                                 sprintf(out_val, 
323                                         "               Killed by %s on %s %d",
324                                         the_score.how, "Dungeon Level", cdun);
325
326                         /* Append a "maximum level" */
327                         if (mdun > cdun) strcat(out_val, format(" (Max %d)", mdun));
328 #endif
329
330                         /* Dump the info */
331                         c_put_str(attr, out_val, n*4 + 3, 0);
332
333                         /* And still another line of info */
334 #ifdef JP
335                         {
336                                 char buf[11];
337
338                                 /* ÆüÉÕ¤ò 19yy/mm/dd ¤Î·Á¼°¤ËÊѹ¹¤¹¤ë */
339                                 if (strlen(when) == 8 && when[2] == '/' && when[5] == '/') {
340                                         sprintf(buf, "%d%s/%.5s", 19 + (when[6] < '8'), when + 6, when);
341                                         when = buf;
342                                 }
343                                 sprintf(out_val,
344                                                 "        (¥æ¡¼¥¶¡¼:%s, ÆüÉÕ:%s, ½ê»ý¶â:%s, ¥¿¡¼¥ó:%s)",
345                                                 user, when, gold, aged);
346                         }
347
348 #else
349                         sprintf(out_val,
350                                 "               (User %s, Date %s, Gold %s, Turn %s).",
351                                 user, when, gold, aged);
352 #endif
353
354                         c_put_str(attr, out_val, n*4 + 4, 0);
355                 }
356
357
358                 /* Wait for response */
359 #ifdef JP
360 prt("[ ESC¤ÇÃæÃÇ, ¤½¤Î¾¤Î¥­¡¼¤Ç³¤±¤Þ¤¹ ]", 23, 21);
361 #else
362                 prt("[Press ESC to quit, any other key to continue.]", 23, 17);
363 #endif
364
365                 j = inkey();
366                 prt("", 23, 0);
367
368                 /* Hack -- notice Escape */
369                 if (j == ESCAPE) break;
370         }
371 }
372
373
374 /*
375  * Hack -- Display the scores in a given range and quit.
376  *
377  * This function is only called from "main.c" when the user asks
378  * to see the "high scores".
379  */
380 void display_scores(int from, int to)
381 {
382         char buf[1024];
383
384         /* Build the filename */
385         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
386
387         /* Open the binary high score file, for reading */
388         highscore_fd = fd_open(buf, O_RDONLY);
389
390         /* Paranoia -- No score file */
391 #ifdef JP
392 if (highscore_fd < 0) quit("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
393 #else
394         if (highscore_fd < 0) quit("Score file unavailable.");
395 #endif
396
397
398         /* Clear screen */
399         Term_clear();
400
401         /* Display the scores */
402         display_scores_aux(from, to, -1, NULL);
403
404         /* Shut the high score file */
405         (void)fd_close(highscore_fd);
406
407         /* Forget the high score fd */
408         highscore_fd = -1;
409
410         /* Quit */
411         quit(NULL);
412 }
413
414
415
416 bool send_world_score(bool do_send)
417 {
418 #ifdef WORLD_SCORE
419         if(send_score && do_send)
420         {
421                 if(easy_band)
422                 {
423 #ifdef JP
424                         msg_print("½é¿´¼Ô¥â¡¼¥É¤Ç¤Ï¥ï¡¼¥ë¥É¥¹¥³¥¢¤ËÅÐÏ¿¤Ç¤­¤Þ¤»¤ó¡£");
425 #else
426                         msg_print("Since you are in the Easy Mode, you cannot send score to world score server.");
427 #endif
428                 }
429 #ifdef JP
430                 else if(get_check("¥¹¥³¥¢¤ò¥¹¥³¥¢¡¦¥µ¡¼¥Ð¤ËÅÐÏ¿¤·¤Þ¤¹¤«? "))
431 #else
432                 else if(get_check("Do you send score to the world score sever? "))
433 #endif
434                 {
435                         errr err;
436                         prt("",0,0);
437 #ifdef JP
438                         prt("Á÷¿®Ãæ¡¥¡¥",0,0);
439 #else
440                         prt("Sending...",0,0);
441 #endif
442                         Term_fresh();
443                         screen_save();
444                         err = report_score();
445                         screen_load();
446                         if (err)
447                         {
448                                 return FALSE;
449                         }
450 #ifdef JP
451                         prt("´°Î»¡£²¿¤«¥­¡¼¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤¡£", 0, 0);
452 #else
453                         prt("Completed.  Hit any key.", 0, 0);
454 #endif
455                         (void)inkey();
456                 }
457                 else return FALSE;
458         }
459 #endif
460         return TRUE;
461 }
462
463 /*
464  * Enters a players name on a hi-score table, if "legal", and in any
465  * case, displays some relevant portion of the high score list.
466  *
467  * Assumes "signals_ignore_tstp()" has been called.
468  */
469 errr top_twenty(void)
470 {
471         int          j;
472
473         high_score   the_score;
474
475         time_t ct = time((time_t*)0);
476
477         /* Clear the record */
478         (void)WIPE(&the_score, high_score);
479
480         /* Save the version */
481         sprintf(the_score.what, "%u.%u.%u",
482                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
483
484         /* Calculate and save the points */
485         sprintf(the_score.pts, "%9ld", (long)total_points());
486         the_score.pts[9] = '\0';
487
488         /* Save the current gold */
489         sprintf(the_score.gold, "%9lu", (long)p_ptr->au);
490         the_score.gold[9] = '\0';
491
492         /* Save the current turn */
493         sprintf(the_score.turns, "%9lu", (long)turn_real(turn));
494         the_score.turns[9] = '\0';
495
496 #ifdef HIGHSCORE_DATE_HACK
497         /* Save the date in a hacked up form (9 chars) */
498         (void)sprintf(the_score.day, "%-.6s %-.2s", ctime(&ct) + 4, ctime(&ct) + 22);
499 #else
500         /* Save the date in standard form (8 chars) */
501 /*      (void)strftime(the_score.day, 9, "%m/%d/%y", localtime(&ct)); */
502         /* Save the date in standard encoded form (9 chars) */
503         strftime(the_score.day, 10, "@%Y%m%d", localtime(&ct));
504 #endif
505
506         /* Save the player name (15 chars) */
507         sprintf(the_score.who, "%-.15s", player_name);
508
509         /* Save the player info XXX XXX XXX */
510         sprintf(the_score.uid, "%7u", player_uid);
511         sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f'));
512         sprintf(the_score.p_r, "%2d", p_ptr->prace);
513         sprintf(the_score.p_c, "%2d", p_ptr->pclass);
514         sprintf(the_score.p_a, "%2d", p_ptr->pseikaku);
515
516         /* Save the level and such */
517         sprintf(the_score.cur_lev, "%3d", p_ptr->lev);
518         sprintf(the_score.cur_dun, "%3d", dun_level);
519         sprintf(the_score.max_lev, "%3d", p_ptr->max_plv);
520         sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]);
521
522         /* Save the cause of death (31 chars) */
523 #ifdef JP
524 #if 0
525         {
526                 /* 2byte Ê¸»ú¤ò¹Íθ¤·¤Ê¤¬¤é¥³¥Ô¡¼(EUC ¤ò²¾Äê) */
527                 int cnt = 0;
528                 unsigned char *d = (unsigned char*)died_from;
529                 unsigned char *h = (unsigned char*)the_score.how;
530                 while(*d && cnt < 31){
531                         if(iskanji(*d)){
532                                 if(cnt + 2 > 31) break;
533                                 *h++ = *d++;
534                                 *h++ = *d++;
535                                 cnt += 2;
536                         }else{
537                                 if(cnt + 1 > 31) break;
538                                 *h++ = *d++;
539                                 cnt++;
540                         }
541                 }
542                 *h = '\0';
543         }
544 #endif
545         if (strlen(died_from) >= 39)
546         {
547                 mb_strlcpy(the_score.how, died_from, 37+1);
548                 strcat(the_score.how, "¡Ä");
549         }
550         else
551                 strcpy(the_score.how, died_from);
552
553 #else
554         sprintf(the_score.how, "%-.31s", died_from);
555 #endif
556
557
558         /* Lock (for writing) the highscore file, or fail */
559         if (fd_lock(highscore_fd, F_WRLCK)) return (1);
560
561         /* Add a new entry to the score list, see where it went */
562         j = highscore_add(&the_score);
563
564         /* Unlock the highscore file, or fail */
565         if (fd_lock(highscore_fd, F_UNLCK)) return (1);
566
567
568         /* Hack -- Display the top fifteen scores */
569         if (j < 10)
570         {
571                 display_scores_aux(0, 15, j, NULL);
572         }
573
574         /* Display the scores surrounding the player */
575         else
576         {
577                 display_scores_aux(0, 5, j, NULL);
578                 display_scores_aux(j - 2, j + 7, j, NULL);
579         }
580
581
582         /* Success */
583         return (0);
584 }
585
586
587 /*
588  * Predict the players location, and display it.
589  */
590 errr predict_score(void)
591 {
592         int          j;
593
594         high_score   the_score;
595
596
597         /* No score file */
598         if (highscore_fd < 0)
599         {
600 #ifdef JP
601 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
602 #else
603                 msg_print("Score file unavailable.");
604 #endif
605
606                 msg_print(NULL);
607                 return (0);
608         }
609
610
611         /* Save the version */
612         sprintf(the_score.what, "%u.%u.%u",
613                 VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
614
615         /* Calculate and save the points */
616         sprintf(the_score.pts, "%9ld", (long)total_points());
617
618         /* Save the current gold */
619         sprintf(the_score.gold, "%9lu", (long)p_ptr->au);
620
621         /* Save the current turn */
622         sprintf(the_score.turns, "%9lu", (long)turn_real(turn));
623
624         /* Hack -- no time needed */
625 #ifdef JP
626 strcpy(the_score.day, "º£Æü");
627 #else
628         strcpy(the_score.day, "TODAY");
629 #endif
630
631
632         /* Save the player name (15 chars) */
633         sprintf(the_score.who, "%-.15s", player_name);
634
635         /* Save the player info XXX XXX XXX */
636         sprintf(the_score.uid, "%7u", player_uid);
637         sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f'));
638         sprintf(the_score.p_r, "%2d", p_ptr->prace);
639         sprintf(the_score.p_c, "%2d", p_ptr->pclass);
640         sprintf(the_score.p_a, "%2d", p_ptr->pseikaku);
641
642         /* Save the level and such */
643         sprintf(the_score.cur_lev, "%3d", p_ptr->lev);
644         sprintf(the_score.cur_dun, "%3d", dun_level);
645         sprintf(the_score.max_lev, "%3d", p_ptr->max_plv);
646         sprintf(the_score.max_dun, "%3d", max_dlv[dungeon_type]);
647
648         /* Hack -- no cause of death */
649 #ifdef JP
650         /* ¤Þ¤À»à¤ó¤Ç¤¤¤Ê¤¤¤È¤­¤Î¼±ÊÌʸ»ú */
651         strcpy(the_score.how, "yet");
652 #else
653         strcpy(the_score.how, "nobody (yet!)");
654 #endif
655
656
657
658         /* See where the entry would be placed */
659         j = highscore_where(&the_score);
660
661
662         /* Hack -- Display the top fifteen scores */
663         if (j < 10)
664         {
665                 display_scores_aux(0, 15, j, &the_score);
666         }
667
668         /* Display some "useful" scores */
669         else
670         {
671                 display_scores_aux(0, 5, -1, NULL);
672                 display_scores_aux(j - 2, j + 7, j, &the_score);
673         }
674
675
676         /* Success */
677         return (0);
678 }
679
680
681
682 /*
683  * show_highclass - selectively list highscores based on class
684  * -KMW-
685  */
686 void show_highclass(int building)
687 {
688
689         register int i = 0, j, m = 0;
690         int pr, pc, pa, clev/*, al*/;
691         high_score the_score;
692         char buf[1024], out_val[256];
693
694         screen_save();
695
696         /* Build the filename */
697         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
698
699         highscore_fd = fd_open(buf, O_RDONLY);
700
701         if (highscore_fd < 0)
702         {
703 #ifdef JP
704 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
705 #else
706                 msg_print("Score file unavailable.");
707 #endif
708
709                 msg_print(NULL);
710                 return;
711         }
712
713         if (highscore_seek(0)) return;
714
715         for (i = 0; i < MAX_HISCORES; i++)
716                 if (highscore_read(&the_score)) break;
717
718         m = 0;
719         j = 0;
720         clev = 0;
721
722         while ((m < 9) && (j < MAX_HISCORES))
723         {
724                 if (highscore_seek(j)) break;
725                 if (highscore_read(&the_score)) break;
726                 pr = atoi(the_score.p_r);
727                 pc = atoi(the_score.p_c);
728                 pa = atoi(the_score.p_a);
729                 clev = atoi(the_score.cur_lev);
730
731 #ifdef JP
732                 sprintf(out_val, "   %3d) %s¤Î%s (¥ì¥Ù¥ë %2d)",
733                     (m + 1), race_info[pr].title,the_score.who, clev);
734 #else
735                 sprintf(out_val, "%3d) %s the %s (Level %2d)",
736                     (m + 1), the_score.who, race_info[pr].title, clev);
737 #endif
738
739                 prt(out_val, (m + 7), 0);
740                 m++;
741                 j++;
742         }
743
744 #ifdef JP
745         sprintf(out_val, "¤¢¤Ê¤¿) %s¤Î%s (¥ì¥Ù¥ë %2d)",
746             race_info[p_ptr->prace].title,player_name, p_ptr->lev);
747 #else
748         sprintf(out_val, "You) %s the %s (Level %2d)",
749             player_name, race_info[p_ptr->prace].title, p_ptr->lev);
750 #endif
751
752         prt(out_val, (m + 8), 0);
753
754         (void)fd_close(highscore_fd);
755         highscore_fd = -1;
756 #ifdef JP
757         prt("²¿¤«¥­¡¼¤ò²¡¤¹¤È¥²¡¼¥à¤ËÌá¤ê¤Þ¤¹",0,0);
758 #else
759         prt("Hit any key to continue",0,0);
760 #endif
761
762         (void)inkey();
763
764         for (j = 5; j < 18; j++) prt("", j, 0);
765         screen_load();
766 }
767
768
769 /*
770  * Race Legends
771  * -KMW-
772  */
773 void race_score(int race_num)
774 {
775         register int i = 0, j, m = 0;
776         int pr, pc, pa, clev, lastlev;
777         high_score the_score;
778         char buf[1024], out_val[256], tmp_str[80];
779
780         lastlev = 0;
781
782         /* rr9: TODO - pluralize the race */
783 #ifdef JP
784 sprintf(tmp_str,"ºÇ¹â¤Î%s", race_info[race_num].title);
785 #else
786         sprintf(tmp_str,"The Greatest of all the %s", race_info[race_num].title);
787 #endif
788
789         prt(tmp_str, 5, 15);
790
791         /* Build the filename */
792         path_build(buf, 1024, ANGBAND_DIR_APEX, "scores.raw");
793
794         highscore_fd = fd_open(buf, O_RDONLY);
795
796         if (highscore_fd < 0)
797         {
798 #ifdef JP
799 msg_print("¥¹¥³¥¢¡¦¥Õ¥¡¥¤¥ë¤¬»ÈÍѤǤ­¤Þ¤»¤ó¡£");
800 #else
801                 msg_print("Score file unavailable.");
802 #endif
803
804                 msg_print(NULL);
805                 return;
806         }
807
808         if (highscore_seek(0)) return;
809
810         for (i = 0; i < MAX_HISCORES; i++)
811         {
812                 if (highscore_read(&the_score)) break;
813         }
814
815         m = 0;
816         j = 0;
817
818         while ((m < 10) || (j < MAX_HISCORES))
819         {
820                 if (highscore_seek(j)) break;
821                 if (highscore_read(&the_score)) break;
822                 pr = atoi(the_score.p_r);
823                 pc = atoi(the_score.p_c);
824                 pa = atoi(the_score.p_a);
825                 clev = atoi(the_score.cur_lev);
826
827                 if (pr == race_num)
828                 {
829 #ifdef JP
830                 sprintf(out_val, "   %3d) %s¤Î%s (¥ì¥Ù¥ë %2d)",
831                             (m + 1), race_info[pr].title, 
832                                 the_score.who,clev);
833 #else
834                         sprintf(out_val, "%3d) %s the %s (Level %3d)",
835                             (m + 1), the_score.who,
836                         race_info[pr].title, clev);
837 #endif
838
839                         prt(out_val, (m + 7), 0);
840                         m++;
841                         lastlev = clev;
842                 }
843                 j++;
844         }
845
846         /* add player if qualified */
847         if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev))
848         {
849 #ifdef JP
850         sprintf(out_val, "¤¢¤Ê¤¿) %s¤Î%s (¥ì¥Ù¥ë %2d)",
851                      race_info[p_ptr->prace].title,player_name, p_ptr->lev);
852 #else
853                 sprintf(out_val, "You) %s the %s (Level %3d)",
854                     player_name, race_info[p_ptr->prace].title, p_ptr->lev);
855 #endif
856
857                 prt(out_val, (m + 8), 0);
858         }
859
860         (void)fd_close(highscore_fd);
861         highscore_fd = -1;
862 }
863
864
865 /*
866  * Race Legends
867  * -KMW-
868  */
869 void race_legends(void)
870 {
871         int i, j;
872
873         for (i = 0; i < MAX_RACES; i++)
874         {
875                 race_score(i);
876 #ifdef JP
877 msg_print("²¿¤«¥­¡¼¤ò²¡¤¹¤È¥²¡¼¥à¤ËÌá¤ê¤Þ¤¹");
878 #else
879                 msg_print("Hit any key to continue");
880 #endif
881
882                 msg_print(NULL);
883                 for (j = 5; j < 19; j++)
884                         prt("", j, 0);
885         }
886 }
887
888
889 /*
890  * Change the player into a King!                       -RAK-
891  */
892 void kingly(void)
893 {
894         /* Hack -- retire in town */
895         dun_level = 0;
896
897         /* Fake death */
898         if (!streq(died_from, "Seppuku"))
899 #ifdef JP
900                 /* °úÂष¤¿¤È¤­¤Î¼±ÊÌʸ»ú */
901                 (void)strcpy(died_from, "ripe");
902 #else
903                 (void)strcpy(died_from, "Ripe Old Age");
904 #endif
905
906
907         /* Restore the experience */
908         p_ptr->exp = p_ptr->max_exp;
909
910         /* Restore the level */
911         p_ptr->lev = p_ptr->max_plv;
912
913         /* Hack -- Instant Gold */
914         p_ptr->au += 10000000L;
915
916         /* Clear screen */
917         Term_clear();
918
919         /* Display a crown */
920         put_str("#", 1, 34);
921         put_str("#####", 2, 32);
922         put_str("#", 3, 34);
923         put_str(",,,  $$$  ,,,", 4, 28);
924         put_str(",,=$   \"$$$$$\"   $=,,", 5, 24);
925         put_str(",$$        $$$        $$,", 6, 22);
926         put_str("*>         <*>         <*", 7, 22);
927         put_str("$$         $$$         $$", 8, 22);
928         put_str("\"$$        $$$        $$\"", 9, 22);
929         put_str("\"$$       $$$       $$\"", 10, 23);
930         put_str("*#########*#########*", 11, 24);
931         put_str("*#########*#########*", 12, 24);
932
933         /* Display a message */
934 #ifdef JP
935 put_str("Veni, Vidi, Vici!", 15, 26);
936 put_str("Í褿¡¢¸«¤¿¡¢¾¡¤Ã¤¿¡ª", 16, 25);
937 put_str(format("°ÎÂç¤Ê¤ë%sËüºÐ¡ª", sp_ptr->winner), 17, 22);
938 #else
939         put_str("Veni, Vidi, Vici!", 15, 26);
940         put_str("I came, I saw, I conquered!", 16, 21);
941         put_str(format("All Hail the Mighty %s!", sp_ptr->winner), 17, 22);
942 #endif
943
944 #ifdef JP
945         do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "¥À¥ó¥¸¥ç¥ó¤Îõº÷¤«¤é°úÂष¤¿¡£");
946         do_cmd_write_nikki(NIKKI_GAMESTART, 1, "-------- ¥²¡¼¥à¥ª¡¼¥Ð¡¼ --------");
947 #else
948         do_cmd_write_nikki(NIKKI_BUNSHOU, 0, "retire exploring dungeons.");
949         do_cmd_write_nikki(NIKKI_GAMESTART, 1, "--------   Game  Over   --------");
950 #endif
951         do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n");
952
953         /* Flush input */
954         flush();
955
956         /* Wait for response */
957         pause_line(23);
958 }