OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / cmd-io / cmd-dump.cpp
1 /*!
2  * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
3  * @date 2014/01/02
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  * This software may be copied and distributed for educational, research,
7  * and not for profit purposes provided that this copyright and statement
8  * are included in all such copies.  Other copyrights may also apply.
9  * 2020 Hourier Rearranged
10  */
11
12 #include "cmd-io/cmd-dump.h"
13 #include "cmd-io/feeling-table.h"
14 #include "core/asking-player.h"
15 #include "dungeon/quest.h"
16 #include "floor/floor-town.h"
17 #include "io-dump/dump-remover.h"
18 #include "io-dump/dump-util.h"
19 #include "io/files-util.h"
20 #include "io/input-key-acceptor.h"
21 #include "io/interpret-pref-file.h"
22 #include "io/read-pref-file.h"
23 #include "locale/english.h"
24 #include "main/sound-of-music.h"
25 #include "mutation/mutation-flag-types.h"
26 #include "player/player-personality-types.h"
27 #include "player/player-status-flags.h"
28 #include "player/player-status.h"
29 #include "system/angband-version.h"
30 #include "system/dungeon-info.h"
31 #include "system/floor-type-definition.h"
32 #include "system/player-type-definition.h"
33 #include "term/gameterm.h"
34 #include "term/screen-processor.h"
35 #include "term/term-color-types.h"
36 #include "timed-effect/player-hallucination.h"
37 #include "timed-effect/timed-effects.h"
38 #include "util/angband-files.h"
39 #include "util/int-char-converter.h"
40 #include "view/display-messages.h"
41 #include "view/display-player.h" // 暫定。後で消す.
42 #include "world/world.h"
43
44 /*!
45  * @brief 画面を再描画するコマンドのメインルーチン
46  * Hack -- redraw the screen
47  * @param player_ptr プレイヤーへの参照ポインタ
48  * @details
49  * Allow absolute file names?
50  */
51 void do_cmd_pref(PlayerType *player_ptr)
52 {
53     const auto input_str = input_string(_("設定変更コマンド: ", "Pref: "), 80);
54     if (!input_str.has_value()) {
55         return;
56     }
57
58     auto buf(input_str.value());
59     (void)interpret_pref_file(player_ptr, buf.data());
60 }
61
62 /*
63  * Interact with "colors"
64  */
65 void do_cmd_colors(PlayerType *player_ptr)
66 {
67     FILE *auto_dump_stream;
68     screen_save();
69     const auto initial_filename = format("%s.prf", player_ptr->base_name);
70     while (true) {
71         term_clear();
72         prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
73         prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
74         prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
75         prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
76         prt(_("コマンド: ", "Command: "), 8, 0);
77         const auto key = inkey();
78         if (key == ESCAPE) {
79             break;
80         }
81
82         switch (key) {
83         case '1': {
84             prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
85             prt(_("ファイル: ", "File: "), 10, 0);
86             const auto ask_result = askfor(70, initial_filename);
87             if (!ask_result) {
88                 continue;
89             }
90
91             (void)process_pref_file(player_ptr, *ask_result, true);
92             term_xtra(TERM_XTRA_REACT, 0);
93             term_redraw();
94             break;
95         }
96         case '2': {
97             constexpr auto mark = "Colors";
98             prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
99             prt(_("ファイル: ", "File: "), 10, 0);
100             const auto ask_result = askfor(70, initial_filename);
101             if (!ask_result) {
102                 continue;
103             }
104
105             const auto &path = path_build(ANGBAND_DIR_USER, *ask_result);
106             if (!open_auto_dump(&auto_dump_stream, path, mark)) {
107                 continue;
108             }
109
110             auto_dump_printf(auto_dump_stream, _("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
111             for (auto i = 0; i < 256; i++) {
112                 int kv = angband_color_table[i][0];
113                 int rv = angband_color_table[i][1];
114                 int gv = angband_color_table[i][2];
115                 int bv = angband_color_table[i][3];
116
117                 auto name = _("未知", "unknown");
118                 if (!kv && !rv && !gv && !bv) {
119                     continue;
120                 }
121
122                 if (i < 16) {
123                     name = color_names[i];
124                 }
125
126                 auto_dump_printf(auto_dump_stream, _("# カラー '%s'\n", "# Color '%s'\n"), name);
127                 auto_dump_printf(auto_dump_stream, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n", i, kv, rv, gv, bv);
128             }
129
130             close_auto_dump(&auto_dump_stream, mark);
131             msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
132             break;
133         }
134         case '3': {
135             static byte a = 0;
136             prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
137             while (true) {
138                 concptr name;
139                 clear_from(10);
140                 for (byte i = 0; i < 16; i++) {
141                     term_putstr(i * 4, 20, -1, a, "###");
142                     term_putstr(i * 4, 22, -1, i, format("%3d", i));
143                 }
144
145                 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
146                 term_putstr(5, 10, -1, TERM_WHITE, format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
147                 term_putstr(5, 12, -1, TERM_WHITE,
148                     format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x", angband_color_table[a][0], angband_color_table[a][1], angband_color_table[a][2],
149                         angband_color_table[a][3]));
150                 term_putstr(0, 14, -1, TERM_WHITE, _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
151                 auto ch = inkey();
152                 if (ch == ESCAPE) {
153                     break;
154                 }
155
156                 switch (ch) {
157                 case 'b':
158                     angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
159                     break;
160                 case 'B':
161                     angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
162                     break;
163                 case 'g':
164                     angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
165                     break;
166                 case 'G':
167                     angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
168                     break;
169                 case 'k':
170                     angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
171                     break;
172                 case 'K':
173                     angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
174                     break;
175                 case 'n':
176                     a++;
177                     break;
178                 case 'N':
179                     a--;
180                     break;
181                 case 'r':
182                     angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
183                     break;
184                 case 'R':
185                     angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
186                     break;
187                 default:
188                     break;
189                 }
190
191                 term_xtra(TERM_XTRA_REACT, 0);
192                 term_redraw();
193             }
194
195             break;
196         }
197         default:
198             bell();
199             break;
200         }
201
202         msg_erase();
203     }
204
205     screen_load();
206 }
207
208 /*
209  * Note something in the message recall
210  */
211 void do_cmd_note(void)
212 {
213     const auto note_opt = input_string(_("メモ: ", "Note: "), 60);
214     if (!note_opt.has_value() || note_opt->empty()) {
215         return;
216     }
217
218     const auto note(note_opt.value());
219     msg_format(_("メモ: %s", "Note: %s"), note.data());
220 }
221
222 /*
223  * Mention the current version
224  */
225 void do_cmd_version(void)
226 {
227     msg_print(get_version());
228 }
229
230 /*
231  * Note that "feeling" is set to zero unless some time has passed.
232  * Note that this is done when the level is GENERATED, not entered.
233  */
234 void do_cmd_feeling(PlayerType *player_ptr)
235 {
236     if (player_ptr->wild_mode) {
237         return;
238     }
239
240     const auto &floor = *player_ptr->current_floor_ptr;
241     if (inside_quest(floor.quest_number) && !inside_quest(random_quest_number(floor, floor.dun_level))) {
242         msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
243         return;
244     }
245
246     if (player_ptr->town_num && !floor.is_in_dungeon()) {
247         if (towns_info[player_ptr->town_num].name == _("荒野", "wilderness")) {
248             msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
249             return;
250         }
251
252         msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
253         return;
254     }
255
256     if (!floor.is_in_dungeon()) {
257         msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
258         return;
259     }
260
261     if (has_good_luck(player_ptr)) {
262         msg_print(do_cmd_feeling_text_lucky[player_ptr->feeling]);
263     } else if (is_echizen(player_ptr)) {
264         msg_print(do_cmd_feeling_text_combat[player_ptr->feeling]);
265     } else {
266         msg_print(do_cmd_feeling_text[player_ptr->feeling]);
267     }
268 }
269
270 /*
271  * Display the time and date
272  * @param player_ptr プレイヤーへの参照ポインタ
273  */
274 void do_cmd_time(PlayerType *player_ptr)
275 {
276     int day, hour, min;
277     extract_day_hour_min(player_ptr, &day, &hour, &min);
278     std::string desc = _("変な時刻だ。", "It is a strange time.");
279     std::string day_buf = (day < MAX_DAYS) ? std::to_string(day) : "*****";
280     constexpr auto mes = _("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s.");
281     msg_format(mes, day_buf.data(), (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
282     std::filesystem::path path;
283     if (!randint0(10) || player_ptr->effects()->hallucination()->is_hallucinated()) {
284         path = path_build(ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
285     } else {
286         path = path_build(ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
287     }
288
289     auto *fff = angband_fopen(path, FileOpenMode::READ);
290     if (!fff) {
291         return;
292     }
293
294     auto full = hour * 100 + min;
295     auto start = 9999;
296     auto end = -9999;
297     auto num = 0;
298     char buf[1024]{};
299     while (!angband_fgets(fff, buf, sizeof(buf))) {
300         if (!buf[0] || (buf[0] == '#')) {
301             continue;
302         }
303         if (buf[1] != ':') {
304             continue;
305         }
306
307         if (buf[0] == 'S') {
308             start = atoi(buf + 2);
309             end = start + 59;
310             continue;
311         }
312
313         if (buf[0] == 'E') {
314             end = atoi(buf + 2);
315             continue;
316         }
317
318         if ((start > full) || (full > end)) {
319             continue;
320         }
321
322         if (buf[0] == 'D') {
323             num++;
324             if (!randint0(num)) {
325                 desc = buf + 2;
326             }
327
328             continue;
329         }
330     }
331
332     msg_print(desc);
333     angband_fclose(fff);
334 }