Changeset 965

Show
Ignore:
Timestamp:
06/28/08 05:57:54 (5 months ago)
Author:
takkaria
Message:

EFfectively rewrite a chunk of the scorefile code so that it now works, more-or-less. This is the patch that was in #552, and thus closes that bug.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/death.c

    r918 r965  
    325325 
    326326        screen_save(); 
    327         top_twenty(); 
     327        show_scores(); 
    328328        screen_load(); 
    329329} 
  • trunk/src/externs.h

    r958 r965  
    3333extern char pf_result[]; 
    3434extern int pf_result_index; 
    35  
    36 /* score.c */ 
    37 extern int score_idx; 
    3835 
    3936/* tables.c */ 
     
    429426 
    430427/* score.c */ 
    431 extern errr enter_score(time_t *death_time); 
     428extern void enter_score(time_t *death_time); 
    432429extern void show_scores(void); 
    433 extern void display_scores(int from, int to); 
    434 extern void top_twenty(void); 
    435430extern void predict_score(void); 
    436431 
  • trunk/src/score.c

    r924 r965  
    2929 * Note that "string comparisons" are thus valid on "pts". 
    3030 */ 
    31  
    32 typedef struct high_score high_score; 
    33  
    34 struct high_score 
     31typedef struct 
    3532{ 
    3633        char what[8];           /* Version info (string) */ 
     
    5855 
    5956        char how[32];           /* Method of death (string) */ 
    60 }; 
    61  
    62  
    63  
    64 /* 
    65  * Hack - save index of player's high score 
    66  */ 
    67 int score_idx = -1; 
     57} high_score; 
    6858 
    6959 
     
    7969 
    8070/* 
    81  * Seek score 'i' in the highscore file 
    82  */ 
    83 static bool highscore_seek(ang_file *f, int i) 
    84 
    85         /* Seek for the requested record */ 
    86         return (file_seek(f, i * sizeof(high_score))); 
    87 
    88  
    89  
    90 /* 
    91  * Read one score from the highscore file 
    92  */ 
    93 static bool highscore_read(ang_file *f, high_score *score) 
    94 
    95         /* Read the record, note failure */ 
    96         return (file_read(f, (char *)score, sizeof(high_score)) > 0); 
    97 
     71 * Read in a highscore file. 
     72 */ 
     73static size_t highscore_read(high_score scores[], size_t sz) 
     74
     75        char fname[1024]; 
     76        ang_file *scorefile; 
     77        size_t i; 
     78 
     79        /* Wipe current scores */ 
     80        C_WIPE(scores, sz, high_score); 
     81 
     82        path_build(fname, sizeof(fname), ANGBAND_DIR_APEX, "scores.raw"); 
     83        scorefile = file_open(fname, MODE_READ, -1); 
     84 
     85        if (!scorefile) return TRUE; 
     86 
     87        for (i = 0; i < sz && 
     88                    file_read(scorefile, (char *)&scores[i], sizeof(high_score)); i++) 
     89                ; 
     90 
     91        file_close(scorefile); 
     92 
     93        return i; 
     94
     95 
    9896 
    9997/* 
     
    10199 * Return the location (0 is best) or -1 on failure 
    102100 */ 
    103 static int highscore_where(ang_file *f, const high_score *score) 
    104 
    105         int i; 
    106         high_score the_score; 
    107  
    108         /* Go to the start of the highscore file */ 
    109         if (!highscore_seek(f, 0)) return (-1); 
     101static size_t highscore_where(const high_score *entry, const high_score scores[], size_t sz) 
     102
     103        size_t i; 
    110104 
    111105        /* Read until we get to a higher score */ 
    112         for (i = 0; i < MAX_HISCORES; i++) 
    113         { 
    114                 if (!highscore_read(f, &the_score)) return (i); 
    115                 if (strcmp(the_score.pts, score->pts) < 0) return (i); 
    116         } 
    117  
    118         /* The "last" entry is always usable */ 
    119         return (MAX_HISCORES - 1); 
    120 
     106        for (i = 0; i < sz; i++) 
     107        { 
     108                long entry_pts = strtoul(entry->pts, NULL, 0); 
     109                long score_pts = strtoul(scores[i].pts, NULL, 0); 
     110 
     111                if (entry_pts >= score_pts) 
     112                        return i; 
     113 
     114                if (scores[i].what[0] == '\0') 
     115                        return i; 
     116        } 
     117 
     118        /* The last entry is always usable */ 
     119        return sz - 1; 
     120
     121 
     122static size_t highscore_add(const high_score *entry, high_score scores[], size_t sz) 
     123
     124        size_t slot = highscore_where(entry, scores, sz); 
     125 
     126        memmove(&scores[slot+1], &scores[slot], sizeof(high_score) * (sz - 1 - slot)); 
     127        memcpy(&scores[slot], entry, sizeof(high_score)); 
     128 
     129        return slot; 
     130
     131 
     132static size_t highscore_count(const high_score scores[], size_t sz) 
     133
     134        size_t i; 
     135        for (i = 0; i < sz; i++) 
     136        { 
     137                if (scores[i].what[0] == '\0') break; 
     138        } 
     139 
     140        return i; 
     141
     142 
    121143 
    122144/* 
     
    124146 * Return the location (0 is best) or -1 on "failure" 
    125147 */ 
    126 static int highscore_add(const high_score *score
    127 { 
    128         int i, slot
    129         bool error = FALSE; 
    130  
    131         high_score tmpscore; 
    132  
    133         ang_file *old, *new, *lok
     148static void highscore_write(const high_score scores[], size_t sz
     149{ 
     150        size_t n
     151 
     152        ang_file *lok; 
     153        ang_file *scorefile; 
     154 
     155        char old_name[1024]
    134156        char cur_name[1024]; 
    135         char old_name[1024]; 
    136157        char new_name[1024]; 
    137158        char lok_name[1024]; 
    138159 
     160        path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old"); 
    139161        path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw"); 
    140         path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old"); 
    141162        path_build(new_name, sizeof(new_name), ANGBAND_DIR_APEX, "scores.new"); 
    142163        path_build(lok_name, sizeof(lok_name), ANGBAND_DIR_APEX, "scores.lok"); 
    143164 
    144165 
    145         old = file_open(cur_name, MODE_READ, -1); 
     166        /* Read in and add new score */ 
     167        n = highscore_count(scores, sz); 
     168 
     169 
     170        /*** Lock scores ***/ 
     171 
     172        if (file_exists(lok_name)) 
     173        { 
     174                msg_print("Lock file in place for scorefile; not writing."); 
     175                return; 
     176        } 
    146177 
    147178        safe_setuid_grab(); 
    148         new = file_open(new_name, MODE_WRITE, FTYPE_RAW); 
    149179        lok = file_open(lok_name, MODE_WRITE, FTYPE_RAW); 
    150         if (new && lok) 
    151                 file_lock(lok); 
     180        file_lock(lok); 
    152181        safe_setuid_drop(); 
    153182 
    154         if (!new || !lok) return -1; 
    155  
    156         /* Determine where the score should go */ 
    157         if (old) 
    158         { 
    159                 slot = highscore_where(old, score); 
    160  
    161                 /* Read entries from the old and write them to the new */ 
    162                 for (i = 0; (i < MAX_HISCORES) && !error; i++) 
    163                 { 
    164                         if (!highscore_seek(old, i)) return (-1); 
    165  
    166                         /* Insert the new one at the right slot */ 
    167                         if (i == slot) 
    168                         { 
    169                                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    170                                 { 
    171                                         error = TRUE; 
    172                                         slot = -1; 
    173                                 } 
    174                         } 
    175          
    176                         /* Read old one, write again */ 
    177                         if (highscore_read(old, &tmpscore)) 
    178                         { 
    179                                 if (!file_write(new, (const char *)&tmpscore, sizeof(high_score))) 
    180                                 { 
    181                                         error = TRUE; 
    182                                         slot = -1; 
    183                                 } 
    184                         } 
    185                 } 
    186  
    187                 file_close(old); 
    188         } 
    189         else 
    190         { 
    191                 slot = 0; 
    192                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    193                 { 
    194                         error = TRUE; 
    195                         slot = -1; 
    196                 } 
    197         } 
    198  
    199         file_close(new); 
    200  
    201         /* Move things around */ 
     183        if (!lok) 
     184        { 
     185                msg_print("Failed to create lock for scorefile; not writing."); 
     186                return; 
     187        } 
     188 
     189 
     190        /*** Open the new file for writing ***/ 
     191 
    202192        safe_setuid_grab(); 
    203  
    204         file_delete(old_name); 
    205  
    206         file_move(cur_name, old_name); 
    207         file_move(new_name, cur_name); 
    208         file_delete(old_name); 
    209  
     193        scorefile = file_open(new_name, MODE_WRITE, FTYPE_RAW); 
     194        safe_setuid_drop(); 
     195 
     196        if (!scorefile) 
     197        { 
     198                msg_print("Failed to open new scorefile for writing."); 
     199 
     200                file_close(lok); 
     201                file_delete(lok_name); 
     202                return; 
     203        } 
     204 
     205        file_write(scorefile, (const char *)&scores, sizeof(high_score)*n); 
     206        file_close(scorefile); 
     207 
     208        /*** Now move things around ***/ 
     209 
     210        safe_setuid_grab(); 
     211 
     212        if (file_exists(old_name) && !file_delete(old_name)) 
     213                msg_print("Couldn't delete old scorefile"); 
     214 
     215        if (file_exists(cur_name) && !file_move(cur_name, old_name)) 
     216                msg_print("Couldn't move old scores.raw out of the way"); 
     217 
     218        if (!file_move(new_name, cur_name)) 
     219                msg_print("Couldn't rename new scorefile to scores.raw"); 
     220 
     221        /* Remove the lock */ 
    210222        file_close(lok); 
     223        file_delete(lok_name); 
     224 
    211225        safe_setuid_drop(); 
    212  
    213         /* Return location used */ 
    214         return (slot); 
    215226} 
    216227 
     
    219230/* 
    220231 * Display the scores in a given range. 
    221  * Assumes the high score list is already open. 
    222  * Only five entries per line, too much info. 
    223  * 
    224  * Mega-Hack -- allow "fake" entry at the given position. 
    225  */ 
    226 static void display_scores_aux(int from, int to, int note, high_score *score) 
     232 */ 
     233static void display_scores_aux(const high_score scores[], int from, int to, int highlight) 
    227234{ 
    228235        char ch; 
     
    231238        int count; 
    232239 
    233         high_score the_score; 
    234  
    235         char out_val[160]; 
    236         char tmp_val[160]; 
    237  
    238         byte attr; 
    239  
    240         ang_file *f; 
    241         char buf[1024]; 
    242  
    243  
    244         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    245         f = file_open(buf, MODE_READ, -1); 
    246         if (!f) return; 
    247240 
    248241        /* Assume we will show the first 10 */ 
     
    255248        for (count = 0; count < MAX_HISCORES; count++) 
    256249        { 
    257                 if (!highscore_read(f, &the_score)) break; 
    258         } 
    259  
    260         /* Hack -- allow "fake" entry to be last */ 
    261         if ((note == count) && score) count++; 
     250                if (!scores[count].what[0]) break; 
     251        } 
    262252 
    263253        /* Forget about the last entries */ 
     
    268258        for (k = from, j = from, place = k+1; k < count; k += 5) 
    269259        { 
     260                char out_val[160]; 
     261                char tmp_val[160]; 
     262 
    270263                /* Clear screen */ 
    271264                Term_clear(); 
     
    274267                put_str(format("%s Hall of Fame", VERSION_NAME), 0, 26); 
    275268 
    276  
    277269                /* Indicate non-top scores */ 
    278270                if (k > 0) 
    279                 { 
    280                         strnfmt(tmp_val, sizeof(tmp_val), "(from position %d)", place); 
    281                         put_str(tmp_val, 0, 40); 
    282                 } 
     271                        put_str(format("(from position %d)", place), 0, 40); 
     272 
    283273 
    284274                /* Dump 5 entries */ 
    285275                for (n = 0; j < count && n < 5; place++, j++, n++) 
    286276                { 
     277                        const high_score *score = &scores[j]; 
     278 
     279                        byte attr; 
     280 
    287281                        int pr, pc, clev, mlev, cdun, mdun; 
    288  
    289282                        cptr user, gold, when, aged; 
    290283 
    291284 
    292285                        /* Hack -- indicate death in yellow */ 
    293                         attr = (j == note) ? TERM_YELLOW : TERM_WHITE; 
    294  
    295  
    296                         /* Mega-Hack -- insert a "fake" record */ 
    297                         if ((note == j) && score) 
    298                         { 
    299                                 the_score = (*score); 
    300                                 attr = TERM_L_GREEN; 
    301                                 score = NULL; 
    302                                 note = -1; 
    303                                 j--; 
    304                         } 
    305  
    306                         /* Read a normal record */ 
     286                        attr = (j == highlight) ? TERM_L_GREEN : TERM_WHITE; 
     287 
     288                        /* Extract the race/class */ 
     289                        pr = atoi(score->p_r); 
     290                        pc = atoi(score->p_c); 
     291 
     292                        /* Extract the level info */ 
     293                        clev = atoi(score->cur_lev); 
     294                        mlev = atoi(score->max_lev); 
     295                        cdun = atoi(score->cur_dun); 
     296                        mdun = atoi(score->max_dun); 
     297 
     298                        /* Hack -- extract the gold and such */ 
     299                        for (user = score->uid; isspace((unsigned char)*user); user++) /* loop */; 
     300                        for (when = score->day; isspace((unsigned char)*when); when++) /* loop */; 
     301                        for (gold = score->gold; isspace((unsigned char)*gold); gold++) /* loop */; 
     302                        for (aged = score->turns; isspace((unsigned char)*aged); aged++) /* loop */; 
     303 
     304                        /* Dump some info */ 
     305                        strnfmt(out_val, sizeof(out_val), 
     306                                "%3d.%9s  %s the %s %s, Level %d", 
     307                                place, score->pts, score->who, 
     308                                p_name + p_info[pr].name, c_name + c_info[pc].name, 
     309                                clev); 
     310 
     311                        /* Append a "maximum level" */ 
     312                        if (mlev > clev) my_strcat(out_val, format(" (Max %d)", mlev), sizeof(out_val)); 
     313 
     314                        /* Dump the first line */ 
     315                        c_put_str(attr, out_val, n*4 + 2, 0); 
     316 
     317 
     318                        /* Died where? */ 
     319                        if (!cdun) 
     320                                strnfmt(out_val, sizeof(out_val), "Killed by %s in the town", score->how); 
    307321                        else 
    308                         { 
    309                                 /* Read the proper record */ 
    310                                 if (!highscore_seek(f, j)) break; 
    311                                 if (!highscore_read(f, &the_score)) break; 
    312                         } 
    313  
    314                         /* Extract the race/class */ 
    315                         pr = atoi(the_score.p_r); 
    316                         pc = atoi(the_score.p_c); 
    317  
    318                         /* Extract the level info */ 
    319                         clev = atoi(the_score.cur_lev); 
    320                         mlev = atoi(the_score.max_lev); 
    321                         cdun = atoi(the_score.cur_dun); 
    322                         mdun = atoi(the_score.max_dun); 
    323  
    324                         /* Hack -- extract the gold and such */ 
    325                         for (user = the_score.uid; isspace((unsigned char)*user); user++) /* loop */; 
    326                         for (when = the_score.day; isspace((unsigned char)*when); when++) /* loop */; 
    327                         for (gold = the_score.gold; isspace((unsigned char)*gold); gold++) /* loop */; 
    328                         for (aged = the_score.turns; isspace((unsigned char)*aged); aged++) /* loop */; 
     322                                strnfmt(out_val, sizeof(out_val), "Killed by %s on dungeon level %d", score->how, cdun); 
     323 
     324                        /* Append a "maximum level" */ 
     325                        if (mdun > cdun) 
     326                                my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 
     327 
     328                        /* Dump the info */ 
     329                        c_put_str(attr, out_val, n*4 + 3, 15); 
     330 
    329331 
    330332                        /* Clean up standard encoded form of "when" */ 
    331333                        if ((*when == '@') && strlen(when) == 9) 
    332334                        { 
    333                                 strnfmt(tmp_val, sizeof(tmp_val), 
    334                                         "%.4s-%.2s-%.2s", 
    335                                         when + 1, when + 5, when + 7); 
     335                                strnfmt(tmp_val, sizeof(tmp_val), "%.4s-%.2s-%.2s", when + 1, when + 5, when + 7); 
    336336                                when = tmp_val; 
    337337                        } 
    338338 
    339                         /* Dump some info */ 
    340                         strnfmt(out_val, sizeof(out_val), 
    341                                 "%3d.%9s  %s the %s %s, Level %d", 
    342                                 place, the_score.pts, the_score.who, 
    343                                 p_name + p_info[pr].name, c_name + c_info[pc].name, 
    344                                 clev); 
    345  
    346                         /* Append a "maximum level" */ 
    347                         if (mlev > clev) my_strcat(out_val, format(" (Max %d)", mlev), sizeof(out_val)); 
    348  
    349                         /* Dump the first line */ 
    350                         c_put_str(attr, out_val, n*4 + 2, 0); 
    351  
    352                         /* Another line of info */ 
    353                         strnfmt(out_val, sizeof(out_val), 
    354                                 "               Killed by %s on dungeon level %d", 
    355                                 the_score.how, cdun); 
    356  
    357                         /* Hack -- some people die in the town */ 
    358                         if (!cdun) 
    359                         { 
    360                                 strnfmt(out_val, sizeof(out_val), 
    361                                         "               Killed by %s in the town", 
    362                                         the_score.how); 
    363                         } 
    364  
    365                         /* Append a "maximum level" */ 
    366                         if (mdun > cdun) my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 
    367  
    368                         /* Dump the info */ 
    369                         c_put_str(attr, out_val, n*4 + 3, 0); 
    370  
    371339                        /* And still another line of info */ 
    372                         strnfmt(out_val, sizeof(out_val), 
    373                                 "               (User %s, Date %s, Gold %s, Turn %s).", 
    374                                 user, when, gold, aged); 
    375                         c_put_str(attr, out_val, n*4 + 4, 0); 
     340                        strnfmt(out_val, sizeof(out_val), "(User %s, Date %s, Gold %s, Turn %s).", user, when, gold, aged); 
     341                        c_put_str(attr, out_val, n*4 + 4, 15); 
    376342                } 
    377343 
     
    386352        } 
    387353 
    388         file_close(f); 
    389354        return; 
    390355} 
    391356 
    392  
    393 /* 
    394  * Hack -- Display the scores in a given range and quit. 
    395  * 
    396  * This function is only called from "main.c" when the user asks 
    397  * to see the "high scores". 
    398  */ 
    399 void display_scores(int from, int to) 
    400 
    401         display_scores_aux(from, to, -1, NULL); 
    402  
    403         prt("[Press any key to exit.]", 23, 17); 
    404         (void)inkey(); 
    405  
    406         quit(NULL); 
    407 
     357static void build_score(high_score *entry, const char *died_from, time_t *death_time) 
     358
     359        WIPE(entry, high_score); 
     360 
     361        /* Save the version */ 
     362        strnfmt(entry->what, sizeof(entry->what), "%s", VERSION_STRING); 
     363 
     364        /* Calculate and save the points */ 
     365        strnfmt(entry->pts, sizeof(entry->pts), "%9lu", (long)total_points()); 
     366 
     367        /* Save the current gold */ 
     368        strnfmt(entry->gold, sizeof(entry->gold), "%9lu", (long)p_ptr->au); 
     369 
     370        /* Save the current turn */ 
     371        strnfmt(entry->turns, sizeof(entry->turns), "%9lu", (long)turn); 
     372 
     373        /* Time of death */ 
     374        if (death_time) 
     375                strftime(entry->day, sizeof(entry->day), "@%Y%m%d", localtime(death_time)); 
     376        else 
     377                my_strcpy(entry->day, "TODAY", sizeof(entry->day)); 
     378 
     379        /* Save the player name (15 chars) */ 
     380        strnfmt(entry->who, sizeof(entry->who), "%-.15s", op_ptr->full_name); 
     381 
     382        /* Save the player info XXX XXX XXX */ 
     383        strnfmt(entry->uid, sizeof(entry->uid), "%7u", player_uid); 
     384        strnfmt(entry->sex, sizeof(entry->sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
     385        strnfmt(entry->p_r, sizeof(entry->p_r), "%2d", p_ptr->prace); 
     386        strnfmt(entry->p_c, sizeof(entry->p_c), "%2d", p_ptr->pclass); 
     387 
     388        /* Save the level and such */ 
     389        strnfmt(entry->cur_lev, sizeof(entry->cur_lev), "%3d", p_ptr->lev); 
     390        strnfmt(entry->cur_dun, sizeof(entry->cur_dun), "%3d", p_ptr->depth); 
     391        strnfmt(entry->max_lev, sizeof(entry->max_lev), "%3d", p_ptr->max_lev); 
     392        strnfmt(entry->max_dun, sizeof(entry->max_dun), "%3d", p_ptr->max_depth); 
     393 
     394        /* No cause of death */ 
     395        my_strcpy(entry->how, died_from, sizeof(entry->how)); 
     396
     397 
    408398 
    409399 
     
    413403 * Assumes "signals_ignore_tstp()" has been called. 
    414404 */ 
    415 errr enter_score(time_t *death_time) 
     405void enter_score(time_t *death_time) 
     406
     407        int j; 
     408 
     409        /* Cheaters are not scored */ 
     410        for (j = OPT_SCORE; j < OPT_MAX; ++j) 
     411        { 
     412                if (!op_ptr->opt[j]) continue; 
     413 
     414                msg_print("Score not registered for cheaters."); 
     415                message_flush(); 
     416                return; 
     417        } 
     418 
     419        /* Wizard-mode pre-empts scoring */ 
     420        if (p_ptr->noscore & (NOSCORE_WIZARD | NOSCORE_DEBUG)) 
     421        { 
     422                msg_print("Score not registered for wizards."); 
     423                message_flush(); 
     424        } 
     425 
     426#ifndef SCORE_BORGS 
     427 
     428        /* Borg-mode pre-empts scoring */ 
     429        else if (p_ptr->noscore & NOSCORE_BORG) 
     430        { 
     431                msg_print("Score not registered for borgs."); 
     432                message_flush(); 
     433        } 
     434 
     435#endif /* SCORE_BORGS */ 
     436 
     437        /* Hack -- Interupted */ 
     438        else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 
     439        { 
     440                msg_print("Score not registered due to interruption."); 
     441                message_flush(); 
     442        } 
     443 
     444        /* Hack -- Quitter */ 
     445        else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 
     446        { 
     447                msg_print("Score not registered due to quitting."); 
     448                message_flush(); 
     449        } 
     450 
     451        /* Add a new entry to the score list, see where it went */ 
     452        else 
     453        { 
     454                high_score entry; 
     455                high_score scores[MAX_HISCORES]; 
     456 
     457                build_score(&entry, p_ptr->died_from, death_time); 
     458 
     459                highscore_read(scores, N_ELEMENTS(scores)); 
     460                highscore_add(&entry, scores, N_ELEMENTS(scores)); 
     461                highscore_write(scores, N_ELEMENTS(scores)); 
     462        } 
     463 
     464        /* Success */ 
     465        return; 
     466
     467 
     468 
     469/* 
     470 * Predict the players location, and display it. 
     471 */ 
     472void predict_score(void) 
    416473{ 
    417474        int j; 
    418475        high_score the_score; 
    419476 
    420         /* Wizard-mode pre-empts scoring */ 
    421         if (p_ptr->noscore & (NOSCORE_WIZARD | NOSCORE_DEBUG)) 
    422         { 
    423                 msg_print("Score not registered for wizards."); 
    424                 message_flush(); 
    425                 score_idx = -1; 
    426                 return (0); 
    427         } 
    428  
    429 #ifndef SCORE_BORGS 
    430  
    431         /* Borg-mode pre-empts scoring */ 
    432         if (p_ptr->noscore & NOSCORE_BORG) 
    433         { 
    434                 msg_print("Score not registered for borgs."); 
    435                 message_flush(); 
    436                 score_idx = -1; 
    437                 return (0); 
    438         } 
    439 #endif /* SCORE_BORGS */ 
    440  
    441         /* Cheaters are not scored */ 
    442         for (j = OPT_SCORE; j < OPT_MAX; ++j) 
    443         { 
    444                 if (!op_ptr->opt[j]) continue; 
    445  
    446                 msg_print("Score not registered for cheaters."); 
    447                 message_flush(); 
    448                 score_idx = -1; 
    449                 return (0); 
    450         } 
    451  
    452         /* Hack -- Interupted */ 
    453         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 
    454         { 
    455                 msg_print("Score not registered due to interruption."); 
    456                 message_flush(); 
    457                 score_idx = -1; 
    458                 return (0); 
    459         } 
    460  
    461         /* Hack -- Quitter */ 
    462         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 
    463         { 
    464                 msg_print("Score not registered due to quitting."); 
    465                 message_flush(); 
    466                 score_idx = -1; 
    467                 return (0); 
    468         } 
    469  
    470  
    471         /* Clear the record */ 
    472         (void)WIPE(&the_score, high_score); 
    473  
    474         /* Save the version */ 
    475         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
    476  
    477         /* Calculate and save the points */ 
    478         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    479         the_score.pts[9] = '\0'; 
    480  
    481         /* Save the current gold */ 
    482         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
    483         the_score.gold[9] = '\0'; 
    484  
    485         /* Save the current turn */ 
    486         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    487         the_score.turns[9] = '\0'; 
    488  
    489         /* Save the date in standard encoded form (9 chars) */ 
    490         strftime(the_score.day, sizeof(the_score.day), "@%Y%m%d", localtime(death_time)); 
    491  
    492         /* Save the player name (15 chars) */ 
    493         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    494  
    495         /* Save the player info XXX XXX XXX */ 
    496         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    497         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    498         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    499         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    500  
    501         /* Save the level and such */ 
    502         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    503         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    504         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    505         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    506  
    507         /* Save the cause of death (31 chars) */ 
    508         strnfmt(the_score.how, sizeof(the_score.how), "%-.31s", p_ptr->died_from); 
    509  
    510         /* Add a new entry to the score list, see where it went */ 
    511         score_idx = highscore_add(&the_score); 
    512  
    513         /* Success */ 
    514         return (0); 
    515 
    516  
    517  
    518  
    519 /* 
    520  * Enters a players name on a hi-score table, if "legal", and in any 
    521  * case, displays some relevant portion of the high score list. 
    522  * 
    523  * Assumes "signals_ignore_tstp()" has been called. 
    524  */ 
    525 void top_twenty(void) 
    526 
    527         /* Clear screen */ 
    528         Term_clear(); 
    529  
    530         /* Player's score unavailable */ 
    531         if (score_idx == -1) 
    532                 display_scores_aux(0, 10, -1, NULL); 
    533  
    534         /* Hack -- Display the top fifteen scores */ 
    535         else if (score_idx < 10) 
    536                 display_scores_aux(0, 15, score_idx, NULL); 
    537  
    538         /* Display the scores surrounding the player */ 
    539         else 
    540         { 
    541                 display_scores_aux(0, 5, score_idx, NULL); 
    542                 display_scores_aux(score_idx - 2, score_idx + 7, score_idx, NULL); 
    543         } 
    544 
    545  
    546  
    547 /* 
    548  * Predict the players location, and display it. 
    549  */ 
    550 void predict_score(void) 
    551 
    552         ang_file *f; 
    553         char buf[1024]; 
    554  
    555         int j; 
    556         high_score the_score; 
    557  
    558         /* Save the version */ 
    559         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
    560  
    561         /* Calculate and save the points */ 
    562         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    563  
    564         /* Save the current gold */ 
    565         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
    566  
    567         /* Save the current turn */ 
    568         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    569  
    570         /* Hack -- no time needed */ 
    571         my_strcpy(the_score.day, "TODAY", sizeof(the_score.day)); 
    572  
    573         /* Save the player name (15 chars) */ 
    574         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    575  
    576         /* Save the player info XXX XXX XXX */ 
    577         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    578         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    579         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    580         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    581  
    582         /* Save the level and such */ 
    583         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    584         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    585         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    586         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    587  
    588         /* No cause of death */ 
    589         my_strcpy(the_score.how, "nobody (yet!)", sizeof(the_score.how)); 
    590  
    591  
    592  
    593         /* Open the highscore file */ 
    594         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    595         f = file_open(buf, MODE_READ, -1); 
    596         if (!f) return; 
    597  
    598         /* See where the entry would be placed */ 
    599         j = highscore_where(f, &the_score); 
    600  
    601         file_close(f); 
    602  
     477        high_score scores[MAX_HISCORES]; 
     478 
     479 
     480        /* Read scores, place current score */ 
     481        highscore_read(scores, N_ELEMENTS(scores)); 
     482        build_score(&the_score, "nobody (yet!)", NULL); 
     483        j = highscore_add(&the_score, scores, N_ELEMENTS(scores)); 
    603484 
    604485        /* Hack -- Display the top fifteen scores */ 
    605486        if (j < 10) 
    606487        { 
    607                 display_scores_aux(0, 15, j, &the_score); 
     488                display_scores_aux(scores, 0, 15, j); 
    608489        } 
    609490 
     
    611492        else 
    612493        { 
    613                 display_scores_aux(0, 5, -1, NULL); 
    614                 display_scores_aux(j - 2, j + 7, j, &the_score); 
    615         } 
    616 
    617  
    618  
     494                display_scores_aux(scores, 0, 5, -1); 
     495                display_scores_aux(scores, j - 2, j + 7, j); 
     496        } 
     497
     498 
     499 
     500/* 
     501 * Show scores. 
     502 */ 
    619503void show_scores(void) 
    620504{ 
     505        high_score scores[MAX_HISCORES]; 
     506 
     507        highscore_read(scores, N_ELEMENTS(scores)); 
     508 
    621509        screen_save(); 
    622510 
     
    625513                predict_score(); 
    626514        else 
    627                 display_scores_aux(0, MAX_HISCORES, -1, NULL); 
     515                display_scores_aux(scores, 0, MAX_HISCORES, -1); 
    628516 
    629517        screen_load(); 
     
    632520        Term_fresh(); 
    633521} 
    634  
  • trunk/src/signals.c

    r918 r965  
    122122                my_strcpy(p_ptr->died_from, "Abortion", sizeof(p_ptr->died_from)); 
    123123 
    124                 /* HACK - Skip the tombscreen if it is already displayed */ 
    125                 if (score_idx == -1) 
    126                 { 
    127                         /* Close stuff */ 
    128                         close_game(); 
    129                 } 
     124                close_game(); 
    130125 
    131126                /* Quit */