Changeset 480

Show
Ignore:
Timestamp:
08/09/07 14:21:39 (1 year ago)
Author:
takkaria
Message:

Move score code into another file (#65, leading to #68).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/Makefile.src

    r479 r480  
    4848        randname.o \ 
    4949        pathfind.o \ 
     50        score.o \ 
    5051        signals.o \ 
    5152        save.o \ 
  • trunk/src/externs.h

    r479 r480  
    3434extern int pf_result_index; 
    3535 
    36 /* files.c */ 
     36/* score.c */ 
    3737extern int score_idx; 
    3838 
     
    324324extern void do_cmd_save_game(void); 
    325325extern long total_points(void); 
    326 extern void show_scores(void); 
    327 extern void display_scores(int from, int to); 
    328326extern void close_game(void); 
    329327extern void exit_game_panic(void); 
     
    476474/* randart.c */ 
    477475extern errr do_randart(u32b randart_seed, bool full); 
     476 
     477/* score.c */ 
     478extern errr enter_score(time_t *death_time); 
     479extern void show_scores(void); 
     480extern void display_scores(int from, int to); 
     481extern void top_twenty(void); 
     482extern void predict_score(void); 
     483 
    478484 
    479485/* signals.c */ 
  • trunk/src/files.c

    r479 r480  
    29602960 
    29612961 
    2962 /* 
    2963  * Seek score 'i' in the highscore file 
    2964  */ 
    2965 static bool highscore_seek(ang_file *f, int i) 
    2966 { 
    2967         /* Seek for the requested record */ 
    2968         return (file_seek(f, i * sizeof(high_score))); 
    2969 } 
    2970  
    2971  
    2972 /* 
    2973  * Read one score from the highscore file 
    2974  */ 
    2975 static bool highscore_read(ang_file *f, high_score *score) 
    2976 { 
    2977         /* Read the record, note failure */ 
    2978         return (file_read(f, (char *)score, sizeof(high_score)) > 0); 
    2979 } 
    2980  
    2981 /* 
    2982  * Just determine where a new score *would* be placed 
    2983  * Return the location (0 is best) or -1 on failure 
    2984  */ 
    2985 static int highscore_where(ang_file *f, const high_score *score) 
    2986 { 
    2987         int i; 
    2988         high_score the_score; 
    2989  
    2990         /* Go to the start of the highscore file */ 
    2991         if (!highscore_seek(f, 0)) return (-1); 
    2992  
    2993         /* Read until we get to a higher score */ 
    2994         for (i = 0; i < MAX_HISCORES; i++) 
    2995         { 
    2996                 if (!highscore_read(f, &the_score)) return (i); 
    2997                 if (strcmp(the_score.pts, score->pts) < 0) return (i); 
    2998         } 
    2999  
    3000         /* The "last" entry is always usable */ 
    3001         return (MAX_HISCORES - 1); 
    3002 } 
    3003  
    3004 /* 
    3005  * Actually place an entry into the high score file 
    3006  * Return the location (0 is best) or -1 on "failure" 
    3007  */ 
    3008 static int highscore_add(const high_score *score) 
    3009 { 
    3010         int i, slot; 
    3011         bool error = FALSE; 
    3012  
    3013         high_score tmpscore; 
    3014  
    3015         ang_file *old, *new, *lok; 
    3016         char cur_name[1024]; 
    3017         char old_name[1024]; 
    3018         char new_name[1024]; 
    3019         char lok_name[1024]; 
    3020  
    3021         path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw"); 
    3022         path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old"); 
    3023         path_build(new_name, sizeof(new_name), ANGBAND_DIR_APEX, "scores.new"); 
    3024         path_build(lok_name, sizeof(lok_name), ANGBAND_DIR_APEX, "scores.lok"); 
    3025  
    3026  
    3027         old = file_open(cur_name, MODE_READ, -1); 
    3028  
    3029         safe_setuid_grab(); 
    3030         new = file_open(new_name, MODE_WRITE, FTYPE_RAW); 
    3031         lok = file_open(lok_name, MODE_WRITE, FTYPE_RAW); 
    3032         if (new && lok) 
    3033                 file_lock(lok); 
    3034         safe_setuid_drop(); 
    3035  
    3036         if (!new || !lok) return -1; 
    3037  
    3038         /* Determine where the score should go */ 
    3039         if (old) 
    3040         { 
    3041                 slot = highscore_where(old, score); 
    3042  
    3043                 /* Read entries from the old and write them to the new */ 
    3044                 for (i = 0; (i < MAX_HISCORES) && !error; i++) 
    3045                 { 
    3046                         if (!highscore_seek(old, i)) return (-1); 
    3047  
    3048                         /* Insert the new one at the right slot */ 
    3049                         if (i == slot) 
    3050                         { 
    3051                                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    3052                                 { 
    3053                                         error = TRUE; 
    3054                                         slot = -1; 
    3055                                 } 
    3056                         } 
    3057          
    3058                         /* Read old one, write again */ 
    3059                         if (highscore_read(old, &tmpscore)) 
    3060                         { 
    3061                                 if (!file_write(new, (const char *)&tmpscore, sizeof(high_score))) 
    3062                                 { 
    3063                                         error = TRUE; 
    3064                                         slot = -1; 
    3065                                 } 
    3066                         } 
    3067                 } 
    3068  
    3069                 file_close(old); 
    3070         } 
    3071         else 
    3072         { 
    3073                 slot = 0; 
    3074                 if (!file_write(new, (const char *)score, sizeof(high_score))) 
    3075                 { 
    3076                         error = TRUE; 
    3077                         slot = -1; 
    3078                 } 
    3079         } 
    3080  
    3081         file_close(new); 
    3082  
    3083         /* Move things around */ 
    3084         safe_setuid_grab(); 
    3085  
    3086         file_delete(old_name); 
    3087  
    3088         file_move(cur_name, old_name); 
    3089         file_move(new_name, cur_name); 
    3090         file_delete(old_name); 
    3091  
    3092         file_close(lok); 
    3093         safe_setuid_drop(); 
    3094  
    3095         /* Return location used */ 
    3096         return (slot); 
    3097 } 
    3098  
    3099  
    3100  
    3101 /* 
    3102  * Display the scores in a given range. 
    3103  * Assumes the high score list is already open. 
    3104  * Only five entries per line, too much info. 
    3105  * 
    3106  * Mega-Hack -- allow "fake" entry at the given position. 
    3107  */ 
    3108 static void display_scores_aux(int from, int to, int note, high_score *score) 
    3109 { 
    3110         char ch; 
    3111  
    3112         int j, k, n, place; 
    3113         int count; 
    3114  
    3115         high_score the_score; 
    3116  
    3117         char out_val[160]; 
    3118         char tmp_val[160]; 
    3119  
    3120         byte attr; 
    3121  
    3122         ang_file *f; 
    3123         char buf[1024]; 
    3124  
    3125  
    3126         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    3127         f = file_open(buf, MODE_READ, -1); 
    3128         if (!f) return; 
    3129  
    3130         /* Assume we will show the first 10 */ 
    3131         if (from < 0) from = 0; 
    3132         if (to < 0) to = 10; 
    3133         if (to > MAX_HISCORES) to = MAX_HISCORES; 
    3134  
    3135  
    3136         /* Hack -- Count the high scores */ 
    3137         for (count = 0; count < MAX_HISCORES; count++) 
    3138         { 
    3139                 if (!highscore_read(f, &the_score)) break; 
    3140         } 
    3141  
    3142         /* Hack -- allow "fake" entry to be last */ 
    3143         if ((note == count) && score) count++; 
    3144  
    3145         /* Forget about the last entries */ 
    3146         if (count > to) count = to; 
    3147  
    3148  
    3149         /* Show 5 per page, until "done" */ 
    3150         for (k = from, j = from, place = k+1; k < count; k += 5) 
    3151         { 
    3152                 /* Clear screen */ 
    3153                 Term_clear(); 
    3154  
    3155                 /* Title */ 
    3156                 put_str(format("%s Hall of Fame", VERSION_NAME), 0, 26); 
    3157  
    3158  
    3159                 /* Indicate non-top scores */ 
    3160                 if (k > 0) 
    3161                 { 
    3162                         strnfmt(tmp_val, sizeof(tmp_val), "(from position %d)", place); 
    3163                         put_str(tmp_val, 0, 40); 
    3164                 } 
    3165  
    3166                 /* Dump 5 entries */ 
    3167                 for (n = 0; j < count && n < 5; place++, j++, n++) 
    3168                 { 
    3169                         int pr, pc, clev, mlev, cdun, mdun; 
    3170  
    3171                         cptr user, gold, when, aged; 
    3172  
    3173  
    3174                         /* Hack -- indicate death in yellow */ 
    3175                         attr = (j == note) ? TERM_YELLOW : TERM_WHITE; 
    3176  
    3177  
    3178                         /* Mega-Hack -- insert a "fake" record */ 
    3179                         if ((note == j) && score) 
    3180                         { 
    3181                                 the_score = (*score); 
    3182                                 attr = TERM_L_GREEN; 
    3183                                 score = NULL; 
    3184                                 note = -1; 
    3185                                 j--; 
    3186                         } 
    3187  
    3188                         /* Read a normal record */ 
    3189                         else 
    3190                         { 
    3191                                 /* Read the proper record */ 
    3192                                 if (!highscore_seek(f, j)) break; 
    3193                                 if (!highscore_read(f, &the_score)) break; 
    3194                         } 
    3195  
    3196                         /* Extract the race/class */ 
    3197                         pr = atoi(the_score.p_r); 
    3198                         pc = atoi(the_score.p_c); 
    3199  
    3200                         /* Extract the level info */ 
    3201                         clev = atoi(the_score.cur_lev); 
    3202                         mlev = atoi(the_score.max_lev); 
    3203                         cdun = atoi(the_score.cur_dun); 
    3204                         mdun = atoi(the_score.max_dun); 
    3205  
    3206                         /* Hack -- extract the gold and such */ 
    3207                         for (user = the_score.uid; isspace((unsigned char)*user); user++) /* loop */; 
    3208                         for (when = the_score.day; isspace((unsigned char)*when); when++) /* loop */; 
    3209                         for (gold = the_score.gold; isspace((unsigned char)*gold); gold++) /* loop */; 
    3210                         for (aged = the_score.turns; isspace((unsigned char)*aged); aged++) /* loop */; 
    3211  
    3212                         /* Clean up standard encoded form of "when" */ 
    3213                         if ((*when == '@') && strlen(when) == 9) 
    3214                         { 
    3215                                 strnfmt(tmp_val, sizeof(tmp_val), 
    3216                                         "%.4s-%.2s-%.2s", 
    3217                                         when + 1, when + 5, when + 7); 
    3218                                 when = tmp_val; 
    3219                         } 
    3220  
    3221                         /* Dump some info */ 
    3222                         strnfmt(out_val, sizeof(out_val), 
    3223                                 "%3d.%9s  %s the %s %s, Level %d", 
    3224                                 place, the_score.pts, the_score.who, 
    3225                                 p_name + p_info[pr].name, c_name + c_info[pc].name, 
    3226                                 clev); 
    3227  
    3228                         /* Append a "maximum level" */ 
    3229                         if (mlev > clev) my_strcat(out_val, format(" (Max %d)", mlev), sizeof(out_val)); 
    3230  
    3231                         /* Dump the first line */ 
    3232                         c_put_str(attr, out_val, n*4 + 2, 0); 
    3233  
    3234                         /* Another line of info */ 
    3235                         strnfmt(out_val, sizeof(out_val), 
    3236                                 "               Killed by %s on dungeon level %d", 
    3237                                 the_score.how, cdun); 
    3238  
    3239                         /* Hack -- some people die in the town */ 
    3240                         if (!cdun) 
    3241                         { 
    3242                                 strnfmt(out_val, sizeof(out_val), 
    3243                                         "               Killed by %s in the town", 
    3244                                         the_score.how); 
    3245                         } 
    3246  
    3247                         /* Append a "maximum level" */ 
    3248                         if (mdun > cdun) my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 
    3249  
    3250                         /* Dump the info */ 
    3251                         c_put_str(attr, out_val, n*4 + 3, 0); 
    3252  
    3253                         /* And still another line of info */ 
    3254                         strnfmt(out_val, sizeof(out_val), 
    3255                                 "               (User %s, Date %s, Gold %s, Turn %s).", 
    3256                                 user, when, gold, aged); 
    3257                         c_put_str(attr, out_val, n*4 + 4, 0); 
    3258                 } 
    3259  
    3260  
    3261                 /* Wait for response */ 
    3262                 prt("[Press ESC to exit, any other key to continue.]", 23, 17); 
    3263                 ch = inkey(); 
    3264                 prt("", 23, 0); 
    3265  
    3266                 /* Hack -- notice Escape */ 
    3267                 if (ch == ESCAPE) break; 
    3268         } 
    3269  
    3270         file_close(f); 
    3271         return; 
    3272 } 
    3273  
    3274  
    3275 /* 
    3276  * Hack -- Display the scores in a given range and quit. 
    3277  * 
    3278  * This function is only called from "main.c" when the user asks 
    3279  * to see the "high scores". 
    3280  */ 
    3281 void display_scores(int from, int to) 
    3282 { 
    3283         display_scores_aux(from, to, -1, NULL); 
    3284  
    3285         prt("[Press any key to exit.]", 23, 17); 
    3286         (void)inkey(); 
    3287  
    3288         quit(NULL); 
    3289 } 
    3290  
    3291  
    3292 /* 
    3293  * Hack - save index of player's high score 
    3294  */ 
    3295 int score_idx = -1; 
    3296  
    3297  
    3298 /* 
    3299  * Enters a players name on a hi-score table, if "legal". 
    3300  * 
    3301  * Assumes "signals_ignore_tstp()" has been called. 
    3302  */ 
    3303 static errr enter_score(void) 
    3304 { 
    3305         int j; 
    3306         high_score the_score; 
    3307  
    3308         /* Wizard-mode pre-empts scoring */ 
    3309         if (p_ptr->noscore & NOSCORE_WIZARD) 
    3310         { 
    3311                 msg_print("Score not registered for wizards."); 
    3312                 message_flush(); 
    3313                 score_idx = -1; 
    3314                 return (0); 
    3315         } 
    3316  
    3317 #ifndef SCORE_BORGS 
    3318  
    3319         /* Borg-mode pre-empts scoring */ 
    3320         if (p_ptr->noscore & NOSCORE_BORG) 
    3321         { 
    3322                 msg_print("Score not registered for borgs."); 
    3323                 message_flush(); 
    3324                 score_idx = -1; 
    3325                 return (0); 
    3326         } 
    3327 #endif /* SCORE_BORGS */ 
    3328  
    3329         /* Cheaters are not scored */ 
    3330         for (j = OPT_SCORE; j < OPT_MAX; ++j) 
    3331         { 
    3332                 if (!op_ptr->opt[j]) continue; 
    3333  
    3334                 msg_print("Score not registered for cheaters."); 
    3335                 message_flush(); 
    3336                 score_idx = -1; 
    3337                 return (0); 
    3338         } 
    3339  
    3340         /* Hack -- Interupted */ 
    3341         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 
    3342         { 
    3343                 msg_print("Score not registered due to interruption."); 
    3344                 message_flush(); 
    3345                 score_idx = -1; 
    3346                 return (0); 
    3347         } 
    3348  
    3349         /* Hack -- Quitter */ 
    3350         if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 
    3351         { 
    3352                 msg_print("Score not registered due to quitting."); 
    3353                 message_flush(); 
    3354                 score_idx = -1; 
    3355                 return (0); 
    3356         } 
    3357  
    3358  
    3359         /* Clear the record */ 
    3360         (void)WIPE(&the_score, high_score); 
    3361  
    3362         /* Save the version */ 
    3363         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
    3364  
    3365         /* Calculate and save the points */ 
    3366         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    3367         the_score.pts[9] = '\0'; 
    3368  
    3369         /* Save the current gold */ 
    3370         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
    3371         the_score.gold[9] = '\0'; 
    3372  
    3373         /* Save the current turn */ 
    3374         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    3375         the_score.turns[9] = '\0'; 
    3376  
    3377         /* Save the date in standard encoded form (9 chars) */ 
    3378         strftime(the_score.day, sizeof(the_score.day), "@%Y%m%d", localtime(&death_time)); 
    3379  
    3380         /* Save the player name (15 chars) */ 
    3381         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    3382  
    3383         /* Save the player info XXX XXX XXX */ 
    3384         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    3385         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    3386         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    3387         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    3388  
    3389         /* Save the level and such */ 
    3390         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    3391         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    3392         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    3393         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    3394  
    3395         /* Save the cause of death (31 chars) */ 
    3396         strnfmt(the_score.how, sizeof(the_score.how), "%-.31s", p_ptr->died_from); 
    3397  
    3398         /* Add a new entry to the score list, see where it went */ 
    3399         score_idx = highscore_add(&the_score); 
    3400  
    3401         /* Success */ 
    3402         return (0); 
    3403 } 
    3404  
    3405  
    3406  
    3407 /* 
    3408  * Enters a players name on a hi-score table, if "legal", and in any 
    3409  * case, displays some relevant portion of the high score list. 
    3410  * 
    3411  * Assumes "signals_ignore_tstp()" has been called. 
    3412  */ 
    3413 static void top_twenty() 
    3414 { 
    3415         /* Clear screen */ 
    3416         Term_clear(); 
    3417  
    3418         /* Player's score unavailable */ 
    3419         if (score_idx == -1) 
    3420                 display_scores_aux(0, 10, -1, NULL); 
    3421  
    3422         /* Hack -- Display the top fifteen scores */ 
    3423         else if (score_idx < 10) 
    3424                 display_scores_aux(0, 15, score_idx, NULL); 
    3425  
    3426         /* Display the scores surrounding the player */ 
    3427         else 
    3428         { 
    3429                 display_scores_aux(0, 5, score_idx, NULL); 
    3430                 display_scores_aux(score_idx - 2, score_idx + 7, score_idx, NULL); 
    3431         } 
    3432 } 
    3433  
    3434  
    3435 /* 
    3436  * Predict the players location, and display it. 
    3437  */ 
    3438 static errr predict_score(void) 
    3439 { 
    3440         ang_file *f; 
    3441         char buf[1024]; 
    3442  
    3443         int j; 
    3444         high_score the_score; 
    3445  
    3446         /* Save the version */ 
    3447         strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 
    3448  
    3449         /* Calculate and save the points */ 
    3450         strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points()); 
    3451  
    3452         /* Save the current gold */ 
    3453         strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 
    3454  
    3455         /* Save the current turn */ 
    3456         strnfmt(the_score.turns, sizeof(the_score.turns), "%9lu", (long)turn); 
    3457  
    3458         /* Hack -- no time needed */ 
    3459         my_strcpy(the_score.day, "TODAY", sizeof(the_score.day)); 
    3460  
    3461         /* Save the player name (15 chars) */ 
    3462         strnfmt(the_score.who, sizeof(the_score.who), "%-.15s", op_ptr->full_name); 
    3463  
    3464         /* Save the player info XXX XXX XXX */ 
    3465         strnfmt(the_score.uid, sizeof(the_score.uid), "%7u", player_uid); 
    3466         strnfmt(the_score.sex, sizeof(the_score.sex), "%c", (p_ptr->psex ? 'm' : 'f')); 
    3467         strnfmt(the_score.p_r, sizeof(the_score.p_r), "%2d", p_ptr->prace); 
    3468         strnfmt(the_score.p_c, sizeof(the_score.p_c), "%2d", p_ptr->pclass); 
    3469  
    3470         /* Save the level and such */ 
    3471         strnfmt(the_score.cur_lev, sizeof(the_score.cur_lev), "%3d", p_ptr->lev); 
    3472         strnfmt(the_score.cur_dun, sizeof(the_score.cur_dun), "%3d", p_ptr->depth); 
    3473         strnfmt(the_score.max_lev, sizeof(the_score.max_lev), "%3d", p_ptr->max_lev); 
    3474         strnfmt(the_score.max_dun, sizeof(the_score.max_dun), "%3d", p_ptr->max_depth); 
    3475  
    3476         /* No cause of death */ 
    3477         my_strcpy(the_score.how, "nobody (yet!)", sizeof(the_score.how)); 
    3478  
    3479  
    3480  
    3481         /* Open the highscore file */ 
    3482         path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); 
    3483         f = file_open(buf, MODE_READ, -1); 
    3484         if (!f) return -1; 
    3485  
    3486         /* See where the entry would be placed */ 
    3487         j = highscore_where(f, &the_score); 
    3488  
    3489         file_close(f); 
    3490  
    3491  
    3492         /* Hack -- Display the top fifteen scores */ 
    3493         if (j < 10) 
    3494         { 
    3495                 display_scores_aux(0, 15, j, &the_score); 
    3496         } 
    3497  
    3498         /* Display some "useful" scores */ 
    3499         else 
    3500         { 
    3501                 display_scores_aux(0, 5, -1, NULL); 
    3502                 display_scores_aux(j - 2, j + 7, j, &the_score); 
    3503         } 
    3504  
    3505  
    3506         /* Success */ 
    3507         return (0); 
    3508 } 
    3509  
    3510  
    3511 void show_scores(void) 
    3512 { 
    3513         screen_save(); 
    3514  
    3515         /* Display the scores */ 
    3516         if (character_generated) 
    3517                 predict_score(); 
    3518         else 
    3519                 display_scores_aux(0, MAX_HISCORES, -1, NULL); 
    3520  
    3521         screen_load(); 
    3522  
    3523         /* Hack - Flush it */ 
    3524         Term_fresh(); 
    3525 } 
    3526  
    3527  
    35282962 
    35292963 
     
    36093043 
    36103044        /* Enter player in high score list */ 
    3611         enter_score(); 
     3045        enter_score(&death_time); 
    36123046 
    36133047        /* Flush all input keys */