| 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 | | |
|---|