X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fscores.c;h=94e655ef3f6ab42fd9022cf704e9ae15af0587bc;hb=606eed97d9f1ed3f09ac43c9afb5d04b5df0c826;hp=e8d61dc96297dea75d06b9b90816036e26f276ea;hpb=a0182347e7ada1f8c695b4c1269758f26e34f232;p=hengband%2Fhengband.git diff --git a/src/scores.c b/src/scores.c index e8d61dc96..94e655ef3 100644 --- a/src/scores.c +++ b/src/scores.c @@ -11,6 +11,31 @@ */ #include "angband.h" +#include "io/signal-handlers.h" +#include "gameterm.h" +#include "util.h" +#include "core.h" + +#include "dungeon.h" +#include "player/race-info-table.h" +#include "player-status.h" +#include "player-class.h" +#include "player-personality.h" +#include "player-sex.h" +#include "io/uid-checker.h" +#include "files.h" +#include "scores.h" +#include "floor.h" +#include "world.h" +#include "io/write-diary.h" +#include "cmd/cmd-dump.h" +#include "report.h" +#include "japanese.h" + + /* + * The "highscore" file descriptor, if available. + */ +int highscore_fd = -1; /*! * @brief i番目のスコア情報にバッファ位置をシークする / Seek score 'i' in the highscore file @@ -47,6 +72,7 @@ static int highscore_write(high_score *score) return (fd_write(highscore_fd, (char*)(score), sizeof(high_score))); } + /*! * @brief スコア情報を全て得るまで繰り返し取得する / Just determine where a new score *would* be placed * @param score スコア情報参照ポインタ @@ -54,31 +80,25 @@ static int highscore_write(high_score *score) */ static int highscore_where(high_score *score) { - int i; - - high_score the_score; - int my_score; - - my_score = atoi(score->pts); - /* Paranoia -- it may not have opened */ - if (highscore_fd < 0) return (-1); + if (highscore_fd < 0) return -1; /* Go to the start of the highscore file */ - if (highscore_seek(0)) return (-1); + if (highscore_seek(0)) return -1; /* Read until we get to a higher score */ - for (i = 0; i < MAX_HISCORES; i++) + high_score the_score; + int my_score = atoi(score->pts); + for (int i = 0; i < MAX_HISCORES; i++) { int old_score; if (highscore_read(&the_score)) return (i); old_score = atoi(the_score.pts); -/* if (strcmp(the_score.pts, score->pts) < 0) return (i); */ if (my_score > old_score) return (i); } /* The "last" entry is always usable */ - return (MAX_HISCORES - 1); + return MAX_HISCORES - 1; } @@ -89,45 +109,40 @@ static int highscore_where(high_score *score) */ static int highscore_add(high_score *score) { - int i, slot; - bool done = FALSE; - - high_score the_score, tmpscore; - - /* Paranoia -- it may not have opened */ - if (highscore_fd < 0) return (-1); + if (highscore_fd < 0) return -1; /* Determine where the score should go */ - slot = highscore_where(score); + int slot = highscore_where(score); /* Hack -- Not on the list */ - if (slot < 0) return (-1); + if (slot < 0) return -1; /* Hack -- prepare to dump the new score */ - the_score = (*score); + high_score the_score = (*score); /* Slide all the scores down one */ - for (i = slot; !done && (i < MAX_HISCORES); i++) + bool done = FALSE; + high_score tmpscore; + for (int i = slot; !done && (i < MAX_HISCORES); i++) { /* Read the old guy, note errors */ - if (highscore_seek(i)) return (-1); + if (highscore_seek(i)) return -1; if (highscore_read(&tmpscore)) done = TRUE; /* Back up and dump the score we were holding */ - if (highscore_seek(i)) return (-1); - if (highscore_write(&the_score)) return (-1); + if (highscore_seek(i)) return -1; + if (highscore_write(&the_score)) return -1; /* Hack -- Save the old score, for the next pass */ the_score = tmpscore; } /* Return location used */ - return (slot); + return slot; } - /*! * @brief 指定された順位範囲でスコアを並べて表示する / Display the scores in a given range. * @param from 順位先頭 @@ -385,8 +400,6 @@ void display_scores_aux(int from, int to, int note, high_score *score) void display_scores(int from, int to) { char buf[1024]; - - /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); /* Open the binary high score file, for reading */ @@ -411,62 +424,56 @@ void display_scores(int from, int to) /*! + * todo プリプロが邪魔していて最初のif文を削除すると到達不能コードが発生する * @brief スコアサーバへの転送処理 + * @param current_player_ptr プレーヤーへの参照ポインタ * @param do_send 実際に転送ア処置を行うか否か * @return 転送が成功したらTRUEを返す */ -bool send_world_score(bool do_send) +bool send_world_score(player_type *current_player_ptr, bool do_send, void(*update_playtime)(void), display_player_pf display_player, map_name_pf map_name) { #ifdef WORLD_SCORE - if(send_score && do_send) + if (send_score && do_send) { - if(easy_band) + if (easy_band) { msg_print(_("初心者モードではワールドスコアに登録できません。", - "Since you are in the Easy Mode, you cannot send score to world score server.")); - } - else if(get_check_strict(_("スコアをスコア・サーバに登録しますか? ", "Do you send score to the world score sever? "), - (CHECK_NO_ESCAPE | CHECK_NO_HISTORY))) - { - errr err; - prt("",0,0); - prt(_("送信中..", "Sending..."),0,0); - Term_fresh(); - screen_save(); - err = report_score(); - screen_load(); - if (err) - { - return FALSE; - } - prt(_("完了。何かキーを押してください。", "Completed. Hit any key."), 0, 0); - (void)inkey(); + "Since you are in the Easy Mode, you cannot send score to world score server.")); + return TRUE; } - else return FALSE; + + bool is_registration = get_check_strict(_("スコアをスコア・サーバに登録しますか? ", "Do you send score to the world score server? "), (CHECK_NO_ESCAPE | CHECK_NO_HISTORY)); + if (!is_registration) return FALSE; + + errr err; + prt("", 0, 0); + prt(_("送信中..", "Sending..."), 0, 0); + Term_fresh(); + screen_save(); + err = report_score(current_player_ptr, update_playtime, display_player, map_name); + screen_load(); + if (err) return FALSE; + + prt(_("完了。何かキーを押してください。", "Completed. Hit any key."), 0, 0); + (void)inkey(); } #endif return TRUE; } + /*! * @brief スコアの過去二十位内ランキングを表示する * Enters a players name on a hi-score table, if "legal", and in any * case, displays some relevant portion of the high score list. + * @param current_player_ptr スコアに適用するための現在プレイヤークリーチャー参照ポインタ * @return エラーコード * @details * Assumes "signals_ignore_tstp()" has been called. */ -errr top_twenty(void) +errr top_twenty(player_type *current_player_ptr) { - int j; - - high_score the_score; - - time_t ct = time((time_t*)0); - - errr err; - - /* Clear the record */ + high_score the_score; (void)WIPE(&the_score, high_score); /* Save the version */ @@ -474,72 +481,67 @@ errr top_twenty(void) FAKE_VER_MAJOR, FAKE_VER_MINOR, FAKE_VER_PATCH); /* Calculate and save the points */ - sprintf(the_score.pts, "%9ld", (long)total_points()); + sprintf(the_score.pts, "%9ld", (long)calc_score(current_player_ptr)); the_score.pts[9] = '\0'; /* Save the current gold */ - sprintf(the_score.gold, "%9lu", (long)p_ptr->au); + sprintf(the_score.gold, "%9lu", (long)current_player_ptr->au); the_score.gold[9] = '\0'; /* Save the current turn */ - sprintf(the_score.turns, "%9lu", (long)turn_real(turn)); + sprintf(the_score.turns, "%9lu", (long)turn_real(current_player_ptr, current_world_ptr->game_turn)); the_score.turns[9] = '\0'; -#ifdef HIGHSCORE_DATE_HACK - /* Save the date in a hacked up form (9 chars) */ - (void)sprintf(the_score.day, "%-.6s %-.2s", ctime(&ct) + 4, ctime(&ct) + 22); -#else - /* Save the date in standard form (8 chars) */ -/* (void)strftime(the_score.day, 9, "%m/%d/%y", localtime(&ct)); */ + time_t ct = time((time_t*)0); + /* Save the date in standard encoded form (9 chars) */ strftime(the_score.day, 10, "@%Y%m%d", localtime(&ct)); -#endif /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", p_ptr->name); + sprintf(the_score.who, "%-.15s", current_player_ptr->name); /* Save the player info */ - sprintf(the_score.uid, "%7u", player_uid); - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); - sprintf(the_score.p_r, "%2d", MIN(p_ptr->prace, MAX_RACES)); - sprintf(the_score.p_c, "%2d", MIN(p_ptr->pclass, MAX_CLASS)); - sprintf(the_score.p_a, "%2d", MIN(p_ptr->pseikaku, MAX_SEIKAKU)); + sprintf(the_score.uid, "%7u", current_player_ptr->player_uid); + sprintf(the_score.sex, "%c", (current_player_ptr->psex ? 'm' : 'f')); + sprintf(the_score.p_r, "%2d", MIN(current_player_ptr->prace, MAX_RACES)); + sprintf(the_score.p_c, "%2d", MIN(current_player_ptr->pclass, MAX_CLASS)); + sprintf(the_score.p_a, "%2d", MIN(current_player_ptr->pseikaku, MAX_SEIKAKU)); /* Save the level and such */ - sprintf(the_score.cur_lev, "%3d", MIN((u16b)p_ptr->lev, 999)); - sprintf(the_score.cur_dun, "%3d", (int)dun_level); - sprintf(the_score.max_lev, "%3d", MIN((u16b)p_ptr->max_plv, 999)); - sprintf(the_score.max_dun, "%3d", (int)max_dlv[dungeon_type]); + sprintf(the_score.cur_lev, "%3d", MIN((u16b)current_player_ptr->lev, 999)); + sprintf(the_score.cur_dun, "%3d", (int)current_player_ptr->current_floor_ptr->dun_level); + sprintf(the_score.max_lev, "%3d", MIN((u16b)current_player_ptr->max_plv, 999)); + sprintf(the_score.max_dun, "%3d", (int)max_dlv[current_player_ptr->dungeon_idx]); /* Save the cause of death (31 chars) */ - if (strlen(p_ptr->died_from) >= sizeof(the_score.how)) + if (strlen(current_player_ptr->died_from) >= sizeof(the_score.how)) { #ifdef JP - my_strcpy(the_score.how, p_ptr->died_from, sizeof(the_score.how) - 2); + my_strcpy(the_score.how, current_player_ptr->died_from, sizeof(the_score.how) - 2); strcat(the_score.how, "…"); #else - my_strcpy(the_score.how, p_ptr->died_from, sizeof(the_score.how) - 3); + my_strcpy(the_score.how, current_player_ptr->died_from, sizeof(the_score.how) - 3); strcat(the_score.how, "..."); #endif } else { - strcpy(the_score.how, p_ptr->died_from); + strcpy(the_score.how, current_player_ptr->died_from); } /* Grab permissions */ safe_setuid_grab(); /* Lock (for writing) the highscore file, or fail */ - err = fd_lock(highscore_fd, F_WRLCK); + errr err = fd_lock(highscore_fd, F_WRLCK); /* Drop permissions */ safe_setuid_drop(); - if (err) return (1); + if (err) return 1; /* Add a new entry to the score list, see where it went */ - j = highscore_add(&the_score); + int j = highscore_add(&the_score); /* Grab permissions */ safe_setuid_grab(); @@ -550,104 +552,88 @@ errr top_twenty(void) /* Drop permissions */ safe_setuid_drop(); - if (err) return (1); - + if (err) return 1; /* Hack -- Display the top fifteen scores */ if (j < 10) { display_scores_aux(0, 15, j, NULL); + return 0; } /* Display the scores surrounding the player */ - else - { - display_scores_aux(0, 5, j, NULL); - display_scores_aux(j - 2, j + 7, j, NULL); - } - - - /* Success */ - return (0); + display_scores_aux(0, 5, j, NULL); + display_scores_aux(j - 2, j + 7, j, NULL); + return 0; } + /*! * @brief プレイヤーの現在のスコアをランキングに挟む / * Predict the players location, and display it. * @return エラーコード */ -errr predict_score(void) +errr predict_score(player_type *current_player_ptr) { - int j; - - high_score the_score; - + high_score the_score; /* No score file */ if (highscore_fd < 0) { msg_print(_("スコア・ファイルが使用できません。", "Score file unavailable.")); msg_print(NULL); - return (0); + return 0; } - /* Save the version */ sprintf(the_score.what, "%u.%u.%u", FAKE_VER_MAJOR, FAKE_VER_MINOR, FAKE_VER_PATCH); /* Calculate and save the points */ - sprintf(the_score.pts, "%9ld", (long)total_points()); + sprintf(the_score.pts, "%9ld", (long)calc_score(current_player_ptr)); /* Save the current gold */ - sprintf(the_score.gold, "%9lu", (long)p_ptr->au); + sprintf(the_score.gold, "%9lu", (long)current_player_ptr->au); /* Save the current turn */ - sprintf(the_score.turns, "%9lu", (long)turn_real(turn)); + sprintf(the_score.turns, "%9lu", (long)turn_real(current_player_ptr, current_world_ptr->game_turn)); /* Hack -- no time needed */ strcpy(the_score.day, _("今日", "TODAY")); /* Save the player name (15 chars) */ - sprintf(the_score.who, "%-.15s", p_ptr->name); + sprintf(the_score.who, "%-.15s", current_player_ptr->name); /* Save the player info */ - sprintf(the_score.uid, "%7u", player_uid); - sprintf(the_score.sex, "%c", (p_ptr->psex ? 'm' : 'f')); - sprintf(the_score.p_r, "%2d", MIN(p_ptr->prace, MAX_RACES)); - sprintf(the_score.p_c, "%2d", MIN(p_ptr->pclass, MAX_CLASS)); - sprintf(the_score.p_a, "%2d", MIN(p_ptr->pseikaku, MAX_SEIKAKU)); + sprintf(the_score.uid, "%7u", current_player_ptr->player_uid); + sprintf(the_score.sex, "%c", (current_player_ptr->psex ? 'm' : 'f')); + sprintf(the_score.p_r, "%2d", MIN(current_player_ptr->prace, MAX_RACES)); + sprintf(the_score.p_c, "%2d", MIN(current_player_ptr->pclass, MAX_CLASS)); + sprintf(the_score.p_a, "%2d", MIN(current_player_ptr->pseikaku, MAX_SEIKAKU)); /* Save the level and such */ - sprintf(the_score.cur_lev, "%3d", MIN((u16b)p_ptr->lev, 999)); - sprintf(the_score.cur_dun, "%3d", (int)dun_level); - sprintf(the_score.max_lev, "%3d", MIN((u16b)p_ptr->max_plv, 999)); - sprintf(the_score.max_dun, "%3d", (int)max_dlv[dungeon_type]); + sprintf(the_score.cur_lev, "%3d", MIN((u16b)current_player_ptr->lev, 999)); + sprintf(the_score.cur_dun, "%3d", (int)current_player_ptr->current_floor_ptr->dun_level); + sprintf(the_score.max_lev, "%3d", MIN((u16b)current_player_ptr->max_plv, 999)); + sprintf(the_score.max_dun, "%3d", (int)max_dlv[current_player_ptr->dungeon_idx]); /* Hack -- no cause of death */ /* まだ死んでいないときの識別文字 */ strcpy(the_score.how, _("yet", "nobody (yet!)")); /* See where the entry would be placed */ - j = highscore_where(&the_score); - + int j = highscore_where(&the_score); /* Hack -- Display the top fifteen scores */ if (j < 10) { display_scores_aux(0, 15, j, &the_score); + return 0; } - /* Display some "useful" scores */ - else - { - display_scores_aux(0, 5, -1, NULL); - display_scores_aux(j - 2, j + 7, j, &the_score); - } - - - /* Success */ - return (0); + display_scores_aux(0, 5, -1, NULL); + display_scores_aux(j - 2, j + 7, j, &the_score); + return 0; } @@ -656,18 +642,10 @@ errr predict_score(void) * show_highclass - selectively list highscores based on class -KMW- * @return なし */ -void show_highclass(void) +void show_highclass(player_type *current_player_ptr) { - - register int i = 0, j, m = 0; - int pr; - PLAYER_LEVEL clev/*, al*/; - high_score the_score; - char buf[1024], out_val[256]; - screen_save(); - - /* Build the filename */ + char buf[1024], out_val[256]; path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); highscore_fd = fd_open(buf, O_RDONLY); @@ -681,13 +659,14 @@ void show_highclass(void) if (highscore_seek(0)) return; - for (i = 0; i < MAX_HISCORES; i++) + high_score the_score; + for (int i = 0; i < MAX_HISCORES; i++) if (highscore_read(&the_score)) break; - m = 0; - j = 0; - clev = 0; - + int m = 0; + int j = 0; + PLAYER_LEVEL clev = 0; + int pr; while ((m < 9) && (j < MAX_HISCORES)) { if (highscore_seek(j)) break; @@ -710,10 +689,10 @@ void show_highclass(void) #ifdef JP sprintf(out_val, "あなた) %sの%s (レベル %2d)", - race_info[p_ptr->prace].title,p_ptr->name, p_ptr->lev); + race_info[current_player_ptr->prace].title,current_player_ptr->name, current_player_ptr->lev); #else sprintf(out_val, "You) %s the %s (Level %2d)", - p_ptr->name, race_info[p_ptr->prace].title, p_ptr->lev); + current_player_ptr->name, race_info[current_player_ptr->prace].title, current_player_ptr->lev); #endif prt(out_val, (m + 8), 0); @@ -728,13 +707,14 @@ void show_highclass(void) screen_load(); } + /*! * @brief スコアランキングの簡易表示(種族毎)サブルーチン / * Race Legends -KMW- * @param race_num 種族ID * @return なし */ -void race_score(int race_num) +void race_score(player_type *current_player_ptr, int race_num) { register int i = 0, j, m = 0; int pr, clev, lastlev; @@ -747,8 +727,6 @@ void race_score(int race_num) sprintf(tmp_str,_("最高の%s", "The Greatest of all the %s"), race_info[race_num].title); prt(tmp_str, 5, 15); - - /* Build the filename */ path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw"); highscore_fd = fd_open(buf, O_RDONLY); @@ -797,14 +775,14 @@ void race_score(int race_num) } /* add player if qualified */ - if ((p_ptr->prace == race_num) && (p_ptr->lev >= lastlev)) + if ((current_player_ptr->prace == race_num) && (current_player_ptr->lev >= lastlev)) { #ifdef JP sprintf(out_val, "あなた) %sの%s (レベル %2d)", - race_info[p_ptr->prace].title,p_ptr->name, p_ptr->lev); + race_info[current_player_ptr->prace].title,current_player_ptr->name, current_player_ptr->lev); #else sprintf(out_val, "You) %s the %s (Level %3d)", - p_ptr->name, race_info[p_ptr->prace].title, p_ptr->lev); + current_player_ptr->name, race_info[current_player_ptr->prace].title, current_player_ptr->lev); #endif prt(out_val, (m + 8), 0); @@ -820,51 +798,50 @@ void race_score(int race_num) * Race Legends -KMW- * @return なし */ -void race_legends(void) +void race_legends(player_type *current_player_ptr) { - int i, j; - - for (i = 0; i < MAX_RACES; i++) + for (int i = 0; i < MAX_RACES; i++) { - race_score(i); + race_score(current_player_ptr, i); msg_print(_("何かキーを押すとゲームに戻ります", "Hit any key to continue")); msg_print(NULL); - for (j = 5; j < 19; j++) + for (int j = 5; j < 19; j++) prt("", j, 0); } } + /*! * @brief 勝利者用の引退演出処理 / * Change the player into a King! -RAK- * @return なし */ -void kingly(void) +void kingly(player_type *winner_ptr) { TERM_LEN wid, hgt; TERM_LEN cx, cy; - bool seppuku = streq(p_ptr->died_from, "Seppuku"); + bool seppuku = streq(winner_ptr->died_from, "Seppuku"); /* Hack -- retire in town */ - dun_level = 0; + winner_ptr->current_floor_ptr->dun_level = 0; /* Fake death */ if (!seppuku) /* 引退したときの識別文字 */ - (void)strcpy(p_ptr->died_from, _("ripe", "Ripe Old Age")); + (void)strcpy(winner_ptr->died_from, _("ripe", "Ripe Old Age")); /* Restore the experience */ - p_ptr->exp = p_ptr->max_exp; + winner_ptr->exp = winner_ptr->max_exp; /* Restore the level */ - p_ptr->lev = p_ptr->max_plv; + winner_ptr->lev = winner_ptr->max_plv; Term_get_size(&wid, &hgt); cy = hgt / 2; cx = wid / 2; /* Hack -- Instant Gold */ - p_ptr->au += 10000000L; + winner_ptr->au += 10000000L; Term_clear(); /* Display a crown */ @@ -895,9 +872,9 @@ void kingly(void) /* If player did Seppuku, that is already written in playrecord */ if (!seppuku) { - do_cmd_write_nikki(NIKKI_BUNSHOU, 0, _("ダンジョンの探索から引退した。", "retired exploring dungeons.")); - do_cmd_write_nikki(NIKKI_GAMESTART, 1, _("-------- ゲームオーバー --------", "-------- Game Over --------")); - do_cmd_write_nikki(NIKKI_BUNSHOU, 1, "\n\n\n\n"); + exe_write_diary(winner_ptr, DIARY_DESCRIPTION, 0, _("ダンジョンの探索から引退した。", "retired exploring dungeons.")); + exe_write_diary(winner_ptr, DIARY_GAMESTART, 1, _("-------- ゲームオーバー --------", "-------- Game Over --------")); + exe_write_diary(winner_ptr, DIARY_DESCRIPTION, 1, "\n\n\n\n"); } /* Flush input */ @@ -906,3 +883,55 @@ void kingly(void) /* Wait for response */ pause_line(hgt - 1); } + + +/*! + * @brief スコアファイル出力 + * Display some character info + * @return なし + */ +bool check_score(player_type *current_player_ptr) +{ + Term_clear(); + + /* No score file */ + if (highscore_fd < 0) + { + msg_print(_("スコア・ファイルが使用できません。", "Score file unavailable.")); + msg_print(NULL); + return FALSE; + } + + /* Wizard-mode pre-empts scoring */ + if (current_world_ptr->noscore & 0x000F) + { + msg_print(_("ウィザード・モードではスコアが記録されません。", "Score not registered for wizards.")); + msg_print(NULL); + return FALSE; + } + + /* Cheaters are not scored */ + if (current_world_ptr->noscore & 0xFF00) + { + msg_print(_("詐欺をやった人はスコアが記録されません。", "Score not registered for cheaters.")); + msg_print(NULL); + return FALSE; + } + + /* Interupted */ + if (!current_world_ptr->total_winner && streq(current_player_ptr->died_from, _("強制終了", "Interrupting"))) + { + msg_print(_("強制終了のためスコアが記録されません。", "Score not registered due to interruption.")); + msg_print(NULL); + return FALSE; + } + + /* Quitter */ + if (!current_world_ptr->total_winner && streq(current_player_ptr->died_from, _("途中終了", "Quitting"))) + { + msg_print(_("途中終了のためスコアが記録されません。", "Score not registered due to quitting.")); + msg_print(NULL); + return FALSE; + } + return TRUE; +}