Ticket #552: score.diff
| File score.diff, 22.4 kB (added by takkaria, 6 months ago) |
|---|
-
score.c
old new 28 28 * 29 29 * Note that "string comparisons" are thus valid on "pts". 30 30 */ 31 32 typedef struct high_score high_score; 33 34 struct high_score 31 typedef struct 35 32 { 36 33 char what[8]; /* Version info (string) */ 37 34 … … 57 54 char max_dun[4]; /* Max Dungeon Level (number) */ 58 55 59 56 char how[32]; /* Method of death (string) */ 60 } ;57 } high_score; 61 58 62 59 63 60 64 61 /* 65 * Hack - save index of player's high score66 */67 int score_idx = -1;68 69 70 71 /*72 62 * Hack -- Calculates the total number of points earned 73 63 */ 74 64 static long total_points(void) … … 78 68 79 69 80 70 /* 81 * Seek score 'i' in the highscore file71 * Read in a highscore file. 82 72 */ 83 static bool highscore_seek(ang_file *f, int i)73 static size_t highscore_read(high_score scores[], size_t sz) 84 74 { 85 /* Seek for the requested record */86 return (file_seek(f, i * sizeof(high_score)));87 } 75 char fname[1024]; 76 ang_file *scorefile; 77 size_t i; 88 78 79 /* Wipe current scores */ 80 C_WIPE(scores, sz, high_score); 89 81 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); 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; 97 94 } 98 95 96 99 97 /* 100 98 * Just determine where a new score *would* be placed 101 99 * Return the location (0 is best) or -1 on failure 102 100 */ 103 static int highscore_where(ang_file *f, const high_score *score)101 static size_t highscore_where(const high_score *entry, const high_score scores[], size_t sz) 104 102 { 105 int i; 106 high_score the_score; 103 size_t i; 107 104 108 /* Go to the start of the highscore file */109 if (!highscore_seek(f, 0)) return (-1);110 111 105 /* Read until we get to a higher score */ 112 for (i = 0; i < MAX_HISCORES; i++)106 for (i = 0; i < sz; i++) 113 107 { 114 if (!highscore_read(f, &the_score)) return (i); 115 if (strcmp(the_score.pts, score->pts) < 0) return (i); 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 116 } 117 117 118 /* The "last"entry is always usable */119 return (MAX_HISCORES - 1);118 /* The last entry is always usable */ 119 return sz - 1; 120 120 } 121 121 122 static 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 132 static 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 143 122 144 /* 123 145 * Actually place an entry into the high score file 124 146 * Return the location (0 is best) or -1 on "failure" 125 147 */ 126 static int highscore_add(const high_score *score)148 static void highscore_write(const high_score scores[], size_t sz) 127 149 { 128 int i, slot; 129 bool error = FALSE; 150 size_t n; 130 151 131 high_score tmpscore; 152 ang_file *lok; 153 ang_file *scorefile; 132 154 133 ang_file *old, *new, *lok;134 char cur_name[1024];135 155 char old_name[1024]; 156 char cur_name[1024]; 136 157 char new_name[1024]; 137 158 char lok_name[1024]; 138 159 139 path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw");140 160 path_build(old_name, sizeof(old_name), ANGBAND_DIR_APEX, "scores.old"); 161 path_build(cur_name, sizeof(cur_name), ANGBAND_DIR_APEX, "scores.raw"); 141 162 path_build(new_name, sizeof(new_name), ANGBAND_DIR_APEX, "scores.new"); 142 163 path_build(lok_name, sizeof(lok_name), ANGBAND_DIR_APEX, "scores.lok"); 143 164 144 165 145 old = file_open(cur_name, MODE_READ, -1); 166 /* Read in and add new score */ 167 n = highscore_count(scores, sz); 146 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 } 177 147 178 safe_setuid_grab(); 148 new = file_open(new_name, MODE_WRITE, FTYPE_RAW);149 179 lok = file_open(lok_name, MODE_WRITE, FTYPE_RAW); 150 if (new && lok) 151 file_lock(lok); 180 file_lock(lok); 152 181 safe_setuid_drop(); 153 182 154 if (!new || !lok) return -1; 155 156 /* Determine where the score should go */ 157 if (old) 183 if (!lok) 158 184 { 159 slot = highscore_where(old, score); 185 msg_print("Failed to create lock for scorefile; not writing."); 186 return; 187 } 160 188 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 189 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 } 190 /*** Open the new file for writing ***/ 186 191 187 file_close(old); 188 } 189 else 192 safe_setuid_grab(); 193 scorefile = file_open(new_name, MODE_WRITE, FTYPE_RAW); 194 safe_setuid_drop(); 195 196 if (!scorefile) 190 197 { 191 slot = 0; 192 if (!file_write(new, (const char *)score, sizeof(high_score))) 193 { 194 error = TRUE; 195 slot = -1; 196 } 198 msg_print("Failed to open new scorefile for writing."); 199 200 file_close(lok); 201 file_delete(lok_name); 202 return; 197 203 } 198 204 199 file_close(new); 205 file_write(scorefile, (const char *)&scores, sizeof(high_score)*n); 206 file_close(scorefile); 200 207 201 /* Move things around */ 208 /*** Now move things around ***/ 209 202 210 safe_setuid_grab(); 203 211 204 file_delete(old_name); 212 if (file_exists(old_name) && !file_delete(old_name)) 213 msg_print("Couldn't delete old scorefile"); 205 214 206 file_move(cur_name, old_name); 207 file_move(new_name, cur_name); 208 file_delete(old_name); 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"); 209 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 */ 210 222 file_close(lok); 211 safe_setuid_drop();223 file_delete(lok_name); 212 224 213 /* Return location used */ 214 return (slot); 225 safe_setuid_drop(); 215 226 } 216 227 217 228 218 229 219 230 /* 220 231 * 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 232 */ 226 static void display_scores_aux( int from, int to, int note, high_score *score)233 static void display_scores_aux(const high_score scores[], int from, int to, int highlight) 227 234 { 228 235 char ch; 229 236 230 237 int j, k, n, place; 231 238 int count; 232 239 233 high_score the_score;234 240 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;247 248 241 /* Assume we will show the first 10 */ 249 242 if (from < 0) from = 0; 250 243 if (to < 0) to = 10; … … 254 247 /* Hack -- Count the high scores */ 255 248 for (count = 0; count < MAX_HISCORES; count++) 256 249 { 257 if (! highscore_read(f, &the_score)) break;250 if (!scores[count].what[0]) break; 258 251 } 259 252 260 /* Hack -- allow "fake" entry to be last */261 if ((note == count) && score) count++;262 263 253 /* Forget about the last entries */ 264 254 if (count > to) count = to; 265 255 … … 267 257 /* Show 5 per page, until "done" */ 268 258 for (k = from, j = from, place = k+1; k < count; k += 5) 269 259 { 260 char out_val[160]; 261 char tmp_val[160]; 262 270 263 /* Clear screen */ 271 264 Term_clear(); 272 265 273 266 /* Title */ 274 267 put_str(format("%s Hall of Fame", VERSION_NAME), 0, 26); 275 268 276 277 269 /* Indicate non-top scores */ 278 270 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); 283 272 273 284 274 /* Dump 5 entries */ 285 275 for (n = 0; j < count && n < 5; place++, j++, n++) 286 276 { 287 int pr, pc, clev, mlev, cdun, mdun;277 const high_score *score = &scores[j]; 288 278 279 byte attr; 280 281 int pr, pc, clev, mlev, cdun, mdun; 289 282 cptr user, gold, when, aged; 290 283 291 284 292 285 /* Hack -- indicate death in yellow */ 293 attr = (j == note) ? TERM_YELLOW: TERM_WHITE;286 attr = (j == highlight) ? TERM_L_GREEN : TERM_WHITE; 294 287 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 */307 else308 {309 /* Read the proper record */310 if (!highscore_seek(f, j)) break;311 if (!highscore_read(f, &the_score)) break;312 }313 314 288 /* Extract the race/class */ 315 pr = atoi( the_score.p_r);316 pc = atoi( the_score.p_c);289 pr = atoi(score->p_r); 290 pc = atoi(score->p_c); 317 291 318 292 /* 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);293 clev = atoi(score->cur_lev); 294 mlev = atoi(score->max_lev); 295 cdun = atoi(score->cur_dun); 296 mdun = atoi(score->max_dun); 323 297 324 298 /* 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 */;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 */; 329 303 330 /* Clean up standard encoded form of "when" */331 if ((*when == '@') && strlen(when) == 9)332 {333 strnfmt(tmp_val, sizeof(tmp_val),334 "%.4s-%.2s-%.2s",335 when + 1, when + 5, when + 7);336 when = tmp_val;337 }338 339 304 /* Dump some info */ 340 305 strnfmt(out_val, sizeof(out_val), 341 306 "%3d.%9s %s the %s %s, Level %d", 342 place, the_score.pts, the_score.who,307 place, score->pts, score->who, 343 308 p_name + p_info[pr].name, c_name + c_info[pc].name, 344 309 clev); 345 310 … … 349 314 /* Dump the first line */ 350 315 c_put_str(attr, out_val, n*4 + 2, 0); 351 316 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 317 357 /* Hack -- some people die in the town*/318 /* Died where? */ 358 319 if (!cdun) 359 { 360 strnfmt(out_val, sizeof(out_val), 361 " Killed by %s in the town", 362 the_score.how); 363 } 320 strnfmt(out_val, sizeof(out_val), "Killed by %s in the town", score->how); 321 else 322 strnfmt(out_val, sizeof(out_val), "Killed by %s on dungeon level %d", score->how, cdun); 364 323 365 324 /* Append a "maximum level" */ 366 if (mdun > cdun) my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 325 if (mdun > cdun) 326 my_strcat(out_val, format(" (Max %d)", mdun), sizeof(out_val)); 367 327 368 328 /* Dump the info */ 369 c_put_str(attr, out_val, n*4 + 3, 0);329 c_put_str(attr, out_val, n*4 + 3, 15); 370 330 331 332 /* Clean up standard encoded form of "when" */ 333 if ((*when == '@') && strlen(when) == 9) 334 { 335 strnfmt(tmp_val, sizeof(tmp_val), "%.4s-%.2s-%.2s", when + 1, when + 5, when + 7); 336 when = tmp_val; 337 } 338 371 339 /* 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); 376 342 } 377 343 378 344 … … 385 351 if (ch == ESCAPE) break; 386 352 } 387 353 388 file_close(f);389 354 return; 390 355 } 391 356 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) 357 static void build_score(high_score *entry, const char *died_from, time_t *death_time) 400 358 { 401 display_scores_aux(from, to, -1, NULL);359 WIPE(entry, high_score); 402 360 403 prt("[Press any key to exit.]", 23, 17);404 (void)inkey();361 /* Save the version */ 362 strnfmt(entry->what, sizeof(entry->what), "%s", VERSION_STRING); 405 363 406 quit(NULL); 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)); 407 396 } 408 397 409 398 399 410 400 /* 411 401 * Enters a players name on a hi-score table, if "legal". 412 402 * 413 403 * Assumes "signals_ignore_tstp()" has been called. 414 404 */ 415 errrenter_score(time_t *death_time)405 void enter_score(time_t *death_time) 416 406 { 417 407 int j; 418 high_score the_score;419 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 420 419 /* Wizard-mode pre-empts scoring */ 421 420 if (p_ptr->noscore & (NOSCORE_WIZARD | NOSCORE_DEBUG)) 422 421 { 423 422 msg_print("Score not registered for wizards."); 424 423 message_flush(); 425 score_idx = -1;426 return (0);427 424 } 428 425 429 426 #ifndef SCORE_BORGS 430 427 431 428 /* Borg-mode pre-empts scoring */ 432 if (p_ptr->noscore & NOSCORE_BORG)429 else if (p_ptr->noscore & NOSCORE_BORG) 433 430 { 434 431 msg_print("Score not registered for borgs."); 435 432 message_flush(); 436 score_idx = -1;437 return (0);438 433 } 434 439 435 #endif /* SCORE_BORGS */ 440 436 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 437 /* Hack -- Interupted */ 453 if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting"))438 else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Interrupting")) 454 439 { 455 440 msg_print("Score not registered due to interruption."); 456 441 message_flush(); 457 score_idx = -1;458 return (0);459 442 } 460 443 461 444 /* Hack -- Quitter */ 462 if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting"))445 else if (!p_ptr->total_winner && streq(p_ptr->died_from, "Quitting")) 463 446 { 464 447 msg_print("Score not registered due to quitting."); 465 448 message_flush(); 466 score_idx = -1;467 return (0);468 449 } 469 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]; 470 456 471 /* Clear the record */ 472 (void)WIPE(&the_score, high_score); 457 build_score(&entry, p_ptr->died_from, death_time); 473 458 474 /* Save the version */ 475 strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 459 highscore_read(scores, N_ELEMENTS(scores)); 460 highscore_add(&entry, scores, N_ELEMENTS(scores)); 461 highscore_write(scores, N_ELEMENTS(scores)); 462 } 476 463 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 464 /* Success */ 514 return (0);465 return; 515 466 } 516 467 517 468 518 519 469 /* 520 * Enters a players name on a hi-score table, if "legal", and in any521 * 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 else540 {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 470 * Predict the players location, and display it. 549 471 */ 550 472 void predict_score(void) 551 473 { 552 ang_file *f;553 char buf[1024];554 555 474 int j; 556 475 high_score the_score; 557 476 558 /* Save the version */ 559 strnfmt(the_score.what, sizeof(the_score.what), "%s", VERSION_STRING); 477 high_score scores[MAX_HISCORES]; 560 478 561 /* Calculate and save the points */562 strnfmt(the_score.pts, sizeof(the_score.pts), "%9lu", (long)total_points());563 479 564 /* Save the current gold */ 565 strnfmt(the_score.gold, sizeof(the_score.gold), "%9lu", (long)p_ptr->au); 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)); 566 484 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 603 604 485 /* Hack -- Display the top fifteen scores */ 605 486 if (j < 10) 606 487 { 607 display_scores_aux( 0, 15, j, &the_score);488 display_scores_aux(scores, 0, 15, j); 608 489 } 609 490 610 491 /* Display some "useful" scores */ 611 492 else 612 493 { 613 display_scores_aux( 0, 5, -1, NULL);614 display_scores_aux( j - 2, j + 7, j, &the_score);494 display_scores_aux(scores, 0, 5, -1); 495 display_scores_aux(scores, j - 2, j + 7, j); 615 496 } 616 497 } 617 498 618 499 500 /* 501 * Show scores. 502 */ 619 503 void show_scores(void) 620 504 { 505 high_score scores[MAX_HISCORES]; 506 507 highscore_read(scores, N_ELEMENTS(scores)); 508 621 509 screen_save(); 622 510 623 511 /* Display the scores */ 624 512 if (character_generated) 625 513 predict_score(); 626 514 else 627 display_scores_aux( 0, MAX_HISCORES, -1, NULL);515 display_scores_aux(scores, 0, MAX_HISCORES, -1); 628 516 629 517 screen_load(); 630 518 631 519 /* Hack - Flush it */ 632 520 Term_fresh(); 633 521 } 634 -
death.c
old new 324 324 (void)title; 325 325 326 326 screen_save(); 327 top_twenty();327 show_scores(); 328 328 screen_load(); 329 329 } 330 330 -
externs.h
old new 33 33 extern char pf_result[]; 34 34 extern int pf_result_index; 35 35 36 /* score.c */37 extern int score_idx;38 39 36 /* tables.c */ 40 37 extern const s16b ddd[9]; 41 38 extern const s16b ddx[10]; … … 430 427 extern errr do_randart(u32b randart_seed, bool full); 431 428 432 429 /* score.c */ 433 extern errrenter_score(time_t *death_time);430 extern void enter_score(time_t *death_time); 434 431 extern void show_scores(void); 435 extern void display_scores(int from, int to);436 extern void top_twenty(void);437 432 extern void predict_score(void); 438 433 439 434 -
signals.c
old new 121 121 /* Mark the savefile */ 122 122 my_strcpy(p_ptr->died_from, "Abortion", sizeof(p_ptr->died_from)); 123 123 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(); 130 125 131 126 /* Quit */ 132 127 quit("interrupt");
