2 * @file game-closer.cpp
8 #include "core/game-closer.h"
9 #include "cmd-io/cmd-save.h"
10 #include "core/asking-player.h"
11 #include "core/score-util.h"
12 #include "core/scores.h"
13 #include "core/stuff-handler.h"
14 #include "floor/floor-save.h"
15 #include "game-option/cheat-options.h"
16 #include "io/files-util.h"
17 #include "io/input-key-acceptor.h"
18 #include "io/signal-handlers.h"
19 #include "io/uid-checker.h"
20 #include "io/write-diary.h"
21 #include "main/music-definitions-table.h"
22 #include "main/sound-of-music.h"
23 #include "player/player-sex.h"
24 #include "player/process-death.h"
25 #include "save/save.h"
26 #include "system/floor-type-definition.h"
27 #include "system/player-type-definition.h"
28 #include "term/gameterm.h"
29 #include "term/screen-processor.h"
30 #include "util/angband-files.h"
31 #include "util/int-char-converter.h"
32 #include "view/display-messages.h"
33 #include "view/display-player.h"
34 #include "view/display-scores.h"
35 #include "world/world.h"
37 static void clear_floor(PlayerType *player_ptr)
39 (void)fd_close(highscore_fd);
41 clear_saved_floor_files(player_ptr);
42 signals_handle_tstp();
45 static void send_world_score_on_closing(PlayerType *player_ptr, bool do_send)
47 if (send_world_score(player_ptr, do_send)) {
51 if (!get_check_strict(
52 player_ptr, _("後でスコアを登録するために待機しますか?", "Stand by for later score registration? "), (CHECK_NO_ESCAPE | CHECK_NO_HISTORY))) {
56 player_ptr->wait_report_score = true;
57 player_ptr->is_dead = false;
58 if (!save_player(player_ptr, SaveType::CLOSE_GAME)) {
59 msg_print(_("セーブ失敗!", "death save failed!"));
64 * @brief ゲームクローズ時、プレイヤーが死亡しているかのチェックを行い死亡していないならば、確認キー入力とスコア表示、現フロアの初期化を行う。
65 * @param player_ptr プレイヤー構造体参照ポインタ。
66 * @return 死亡していればTRUE, まだ生きているならば各処理を済ませた上ででFALSE。
68 static bool check_death(PlayerType *player_ptr)
70 if (player_ptr->is_dead) {
74 do_cmd_save_game(player_ptr, false);
75 prt(_("リターンキーか ESC キーを押して下さい。", "Press Return (or Escape)."), 0, 40);
76 play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_EXIT);
77 if (inkey() != ESCAPE) {
78 predict_score(player_ptr);
81 clear_floor(player_ptr);
86 * @brief 勝利者用の引退演出処理 /
87 * Change the player into a King! -RAK-
89 static void kingly(PlayerType *player_ptr)
91 bool seppuku = streq(player_ptr->died_from, "Seppuku");
92 player_ptr->current_floor_ptr->dun_level = 0;
95 player_ptr->died_from = _("ripe", "Ripe Old Age");
98 player_ptr->exp = player_ptr->max_exp;
99 player_ptr->lev = player_ptr->max_plv;
100 player_ptr->au += 10000000L;
104 put_str("#####", 2, 37);
106 put_str(",,, $$$ ,,,", 4, 33);
107 put_str(",,=$ \"$$$$$\" $=,,", 5, 29);
108 put_str(",$$ $$$ $$,", 6, 27);
109 put_str("*> <*> <*", 7, 27);
110 put_str("$$ $$$ $$", 8, 27);
111 put_str("\"$$ $$$ $$\"", 9, 27);
112 put_str("\"$$ $$$ $$\"", 10, 28);
113 put_str("*#########*#########*", 11, 29);
114 put_str("*#########*#########*", 12, 29);
117 put_str("Veni, Vidi, Vici!", 15, 31);
118 put_str("来た、見た、勝った!", 16, 30);
119 put_str(format("偉大なる%s万歳!", sp_ptr->winner), 17, 29);
121 put_str("Veni, Vidi, Vici!", 15, 31);
122 put_str("I came, I saw, I conquered!", 16, 26);
123 put_str(format("All Hail the Mighty %s!", sp_ptr->winner), 17, 27);
127 exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, _("ダンジョンの探索から引退した。", "retired exploring dungeons."));
128 exe_write_diary(player_ptr, DIARY_GAMESTART, 1, _("-------- ゲームオーバー --------", "-------- Game Over --------"));
129 exe_write_diary(player_ptr, DIARY_DESCRIPTION, 1, "\n\n\n\n");
133 pause_line(MAIN_TERM_MIN_ROWS - 1);
138 * Close up the current game (player may or may not be dead)
139 * @param player_ptr プレイヤーへの参照ポインタ
142 * This function is called only from "main.c" and "signals.c".
145 void close_game(PlayerType *player_ptr)
147 handle_stuff(player_ptr);
150 signals_ignore_tstp();
152 w_ptr->character_icky_depth = 1;
153 const auto &path = path_build(ANGBAND_DIR_APEX, "scores.raw");
154 safe_setuid_grab(player_ptr);
155 highscore_fd = fd_open(path, O_RDWR);
158 if (!check_death(player_ptr)) {
162 TermCenteredOffsetSetter tcos(MAIN_TERM_MIN_COLS, MAIN_TERM_MIN_ROWS);
163 if (w_ptr->total_winner) {
168 if (!cheat_save || get_check(_("死んだデータをセーブしますか? ", "Save death? "))) {
170 w_ptr->sf_play_time += w_ptr->play_time;
172 if (!save_player(player_ptr, SaveType::CLOSE_GAME)) {
173 msg_print(_("セーブ失敗!", "death save failed!"));
179 print_tomb(player_ptr);
181 show_death_info(player_ptr);
183 if (check_score(player_ptr)) {
184 send_world_score_on_closing(player_ptr, do_send);
185 if (!player_ptr->wait_report_score) {
186 (void)top_twenty(player_ptr);
188 } else if (highscore_fd >= 0) {
189 display_scores(0, 10, -1, nullptr);
192 clear_floor(player_ptr);