OSDN Git Service

[Refactor] #38862 Moved save/load.c/h to io/
[hengband/hengband.git] / src / core / game-closer.c
1 #include "system/angband.h"
2 #include "core/game-closer.h"
3 #include "cmd/cmd-save.h"
4 #include "core/stuff-handler.h"
5 #include "io/signal-handlers.h"
6 #include "io/uid-checker.h"
7 #include "main/music-definitions-table.h"
8 #include "player/process-death.h"
9 #include "io/save.h"
10 #include "scores.h"
11 #include "view/display-main-window.h"
12 #include "view/display-player.h"
13 #include "world/world.h"
14
15 static void clear_floor(player_type* player_ptr)
16 {
17     (void)fd_close(highscore_fd);
18     highscore_fd = -1;
19     clear_saved_floor_files(player_ptr);
20     signals_handle_tstp();
21 }
22
23 static void send_world_score_on_closing(player_type* player_ptr, bool do_send)
24 {
25     if (send_world_score(player_ptr, do_send, update_playtime, display_player, map_name))
26         return;
27
28     if (!get_check_strict(_("後でスコアを登録するために待機しますか?", "Stand by for later score registration? "),
29             (CHECK_NO_ESCAPE | CHECK_NO_HISTORY)))
30         return;
31
32     player_ptr->wait_report_score = TRUE;
33     player_ptr->is_dead = FALSE;
34     if (!save_player(player_ptr))
35         msg_print(_("セーブ失敗!", "death save failed!"));
36 }
37
38 static bool check_death(player_type* player_ptr)
39 {
40     if (player_ptr->is_dead)
41         return TRUE;
42
43     do_cmd_save_game(player_ptr, FALSE);
44     prt(_("リターンキーか ESC キーを押して下さい。", "Press Return (or Escape)."), 0, 40);
45     play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_EXIT);
46     if (inkey() != ESCAPE)
47         predict_score(player_ptr);
48
49     clear_floor(player_ptr);
50     return FALSE;
51 }
52
53 /*!
54  * @brief ゲーム終了処理 /
55  * Close up the current game (player may or may not be dead)
56  * @param creature_ptr プレーヤーへの参照ポインタ
57  * @return なし
58  * @details
59  * <pre>
60  * This function is called only from "main.c" and "signals.c".
61  * </pre>
62  */
63 void close_game(player_type* player_ptr)
64 {
65     bool do_send = TRUE;
66     handle_stuff(player_ptr);
67     msg_print(NULL);
68     flush();
69     signals_ignore_tstp();
70
71     current_world_ptr->character_icky = TRUE;
72     char buf[1024];
73     path_build(buf, sizeof(buf), ANGBAND_DIR_APEX, "scores.raw");
74     safe_setuid_grab();
75     highscore_fd = fd_open(buf, O_RDWR);
76     safe_setuid_drop();
77
78     if (!check_death(player_ptr))
79         return;
80
81     if (current_world_ptr->total_winner)
82         kingly(player_ptr);
83
84     if (!cheat_save || get_check(_("死んだデータをセーブしますか? ", "Save death? "))) {
85         if (!save_player(player_ptr))
86             msg_print(_("セーブ失敗!", "death save failed!"));
87     } else
88         do_send = FALSE;
89
90     print_tomb(player_ptr);
91     flush();
92     show_death_info(player_ptr, update_playtime, display_player, map_name);
93     Term_clear();
94     if (check_score(player_ptr)) {
95         send_world_score_on_closing(player_ptr, do_send);
96         if (!player_ptr->wait_report_score)
97             (void)top_twenty(player_ptr);
98     } else if (highscore_fd >= 0) {
99         display_scores_aux(0, 10, -1, NULL);
100     }
101
102     clear_floor(player_ptr);
103 }