OSDN Git Service

[Refactor] #39964 Separated autopick-entry.c/h from autopick.c
[hengband/hengband.git] / src / cmd / cmd-dump.c
1 /*!
2  * @file cmd-dump.c
3  * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
4  * @date 2014/01/02
5  * @author
6  * <pre>
7  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  * </pre>
12  * @details
13  * <pre>
14  * A set of functions to maintain automatic dumps of various kinds.
15  * The dump commands of original Angband simply add new lines to
16  * existing files; these files will become bigger and bigger unless
17  * an user deletes some or all of these files by hand at some
18  * point.
19  * These three functions automatically delete old dumped lines
20  * before adding new ones.  Since there are various kinds of automatic
21  * dumps in a single file, we add a header and a footer with a type
22  * name for every automatic dump, and kill old lines only when the
23  * lines have the correct type of header and footer.
24  * We need to be quite paranoid about correctness; the user might
25  * (mistakenly) edit the file by hand, and see all their work come
26  * to nothing on the next auto dump otherwise.  The current code only
27  * detects changes by noting inconsistencies between the actual number
28  * of lines and the number written in the footer.  Note that this will
29  * not catch single-line edits.
30  * </pre>
31  */
32
33 #include "angband.h"
34 #include "cmd/cmd-dump.h"
35 #include "cmd/dump-util.h"
36 #include "gameterm.h"
37 #include "core.h" // 暫定。後で消す.
38 #include "io/read-pref-file.h"
39 #include "io/interpret-pref-file.h"
40
41 #include "world.h"
42 #include "view/display-player.h" // 暫定。後で消す.
43 #include "player-personality.h"
44 #include "quest.h"
45 #include "artifact.h"
46 #include "floor-town.h"
47 #include "cmd/feeling-table.h"
48 #include "english.h"
49
50 #include "chuukei.h"
51
52 /*!
53  * @brief prefファイルを選択して処理する /
54  * Ask for a "user pref line" and process it
55  * @brief prf出力内容を消去する /
56  * Remove old lines automatically generated before.
57  * @param orig_file 消去を行うファイル名
58  */
59 static void remove_auto_dump(concptr orig_file, concptr auto_dump_mark)
60 {
61         char buf[1024];
62         bool between_mark = FALSE;
63         bool changed = FALSE;
64         int line_num = 0;
65         long header_location = 0;
66         char header_mark_str[80];
67         char footer_mark_str[80];
68
69         sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
70         sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
71         size_t mark_len = strlen(footer_mark_str);
72
73         FILE *orig_fff;
74         orig_fff = my_fopen(orig_file, "r");
75         if (!orig_fff) return;
76
77         FILE *tmp_fff = NULL;
78         char tmp_file[FILE_NAME_SIZE];
79         if (!open_temporary_file(&tmp_fff, tmp_file)) return;
80
81         while (TRUE)
82         {
83                 if (my_fgets(orig_fff, buf, sizeof(buf)))
84                 {
85                         if (between_mark)
86                         {
87                                 fseek(orig_fff, header_location, SEEK_SET);
88                                 between_mark = FALSE;
89                                 continue;
90                         }
91                         else
92                         {
93                                 break;
94                         }
95                 }
96
97                 if (!between_mark)
98                 {
99                         if (!strcmp(buf, header_mark_str))
100                         {
101                                 header_location = ftell(orig_fff);
102                                 line_num = 0;
103                                 between_mark = TRUE;
104                                 changed = TRUE;
105                         }
106                         else
107                         {
108                                 fprintf(tmp_fff, "%s\n", buf);
109                         }
110
111                         continue;
112                 }
113
114                 if (!strncmp(buf, footer_mark_str, mark_len))
115                 {
116                         int tmp;
117                         if (!sscanf(buf + mark_len, " (%d)", &tmp)
118                                 || tmp != line_num)
119                         {
120                                 fseek(orig_fff, header_location, SEEK_SET);
121                         }
122
123                         between_mark = FALSE;
124                         continue;
125                 }
126
127                 line_num++;
128         }
129
130         my_fclose(orig_fff);
131         my_fclose(tmp_fff);
132
133         if (changed)
134         {
135                 tmp_fff = my_fopen(tmp_file, "r");
136                 orig_fff = my_fopen(orig_file, "w");
137                 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
138                         fprintf(orig_fff, "%s\n", buf);
139
140                 my_fclose(orig_fff);
141                 my_fclose(tmp_fff);
142         }
143
144         fd_kill(tmp_file);
145 }
146
147
148 #ifdef JP
149 #else
150 /*!
151  * @brief Return suffix of ordinal number
152  * @param num number
153  * @return pointer of suffix string.
154  */
155 concptr get_ordinal_number_suffix(int num)
156 {
157         num = ABS(num) % 100;
158         switch (num % 10)
159         {
160         case 1:
161                 return (num == 11) ? "th" : "st";
162         case 2:
163                 return (num == 12) ? "th" : "nd";
164         case 3:
165                 return (num == 13) ? "th" : "rd";
166         default:
167                 return "th";
168         }
169 }
170 #endif
171
172 /*!
173  * @brief 画面を再描画するコマンドのメインルーチン
174  * Hack -- redraw the screen
175  * @param creature_ptr プレーヤーへの参照ポインタ
176  * @return なし
177  * @details
178  * Allow absolute file names?
179  */
180 void do_cmd_pref(player_type *creature_ptr)
181 {
182         char buf[80];
183         strcpy(buf, "");
184         if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
185
186         (void)interpret_pref_file(creature_ptr, buf);
187 }
188
189
190 /*
191  * Interact with "colors"
192  */
193 void do_cmd_colors(player_type *creature_ptr)
194 {
195         int i;
196         char tmp[160];
197         char buf[1024];
198         FILE *auto_dump_stream;
199         FILE_TYPE(FILE_TYPE_TEXT);
200         screen_save();
201         while (TRUE)
202         {
203                 Term_clear();
204                 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
205                 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
206                 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
207                 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
208                 prt(_("コマンド: ", "Command: "), 8, 0);
209                 i = inkey();
210                 if (i == ESCAPE) break;
211
212                 if (i == '1')
213                 {
214                         prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
215                         prt(_("ファイル: ", "File: "), 10, 0);
216                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
217                         if (!askfor(tmp, 70)) continue;
218
219                         (void)process_pref_file(creature_ptr, tmp);
220                         Term_xtra(TERM_XTRA_REACT, 0);
221                         Term_redraw();
222                 }
223                 else if (i == '2')
224                 {
225                         static concptr mark = "Colors";
226                         prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
227                         prt(_("ファイル: ", "File: "), 10, 0);
228                         sprintf(tmp, "%s.prf", creature_ptr->base_name);
229                         if (!askfor(tmp, 70)) continue;
230
231                         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
232                         if (!open_auto_dump(&auto_dump_stream, buf, mark)) continue;
233
234                         auto_dump_printf(auto_dump_stream, _("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
235                         for (i = 0; i < 256; i++)
236                         {
237                                 int kv = angband_color_table[i][0];
238                                 int rv = angband_color_table[i][1];
239                                 int gv = angband_color_table[i][2];
240                                 int bv = angband_color_table[i][3];
241
242                                 concptr name = _("未知", "unknown");
243                                 if (!kv && !rv && !gv && !bv) continue;
244
245                                 if (i < 16) name = color_names[i];
246
247                                 auto_dump_printf(auto_dump_stream, _("# カラー '%s'\n", "# Color '%s'\n"), name);
248                                 auto_dump_printf(auto_dump_stream, "V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
249                                         i, kv, rv, gv, bv);
250                         }
251
252                         close_auto_dump(&auto_dump_stream, mark);
253                         msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
254                 }
255                 else if (i == '3')
256                 {
257                         static byte a = 0;
258                         prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
259                         while (TRUE)
260                         {
261                                 concptr name;
262                                 clear_from(10);
263                                 for (byte j = 0; j < 16; j++)
264                                 {
265                                         Term_putstr(j * 4, 20, -1, a, "###");
266                                         Term_putstr(j * 4, 22, -1, j, format("%3d", j));
267                                 }
268
269                                 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
270                                 Term_putstr(5, 10, -1, TERM_WHITE,
271                                         format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
272                                 Term_putstr(5, 12, -1, TERM_WHITE,
273                                         format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
274                                                 angband_color_table[a][0],
275                                                 angband_color_table[a][1],
276                                                 angband_color_table[a][2],
277                                                 angband_color_table[a][3]));
278                                 Term_putstr(0, 14, -1, TERM_WHITE,
279                                         _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
280                                 i = inkey();
281                                 if (i == ESCAPE) break;
282
283                                 if (i == 'n') a = (byte)(a + 1);
284                                 if (i == 'N') a = (byte)(a - 1);
285                                 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
286                                 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
287                                 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
288                                 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
289                                 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
290                                 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
291                                 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
292                                 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
293
294                                 Term_xtra(TERM_XTRA_REACT, 0);
295                                 Term_redraw();
296                         }
297                 }
298                 else
299                 {
300                         bell();
301                 }
302
303                 msg_erase();
304         }
305
306         screen_load();
307 }
308
309
310 /*
311  * Note something in the message recall
312  */
313 void do_cmd_note(void)
314 {
315         char buf[80];
316         strcpy(buf, "");
317         if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
318         if (!buf[0] || (buf[0] == ' ')) return;
319
320         msg_format(_("メモ: %s", "Note: %s"), buf);
321 }
322
323
324 /*
325  * Mention the current version
326  */
327 void do_cmd_version(void)
328 {
329 #if FAKE_VER_EXTRA > 0
330         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
331                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
332 #else
333         msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
334                 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
335 #endif
336 }
337
338
339 /*
340  * Note that "feeling" is set to zero unless some time has passed.
341  * Note that this is done when the level is GENERATED, not entered.
342  */
343 void do_cmd_feeling(player_type *creature_ptr)
344 {
345         if (creature_ptr->wild_mode) return;
346
347         if (creature_ptr->current_floor_ptr->inside_quest && !random_quest_number(creature_ptr, creature_ptr->current_floor_ptr->dun_level))
348         {
349                 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
350                 return;
351         }
352
353         if (creature_ptr->town_num && !creature_ptr->current_floor_ptr->dun_level)
354         {
355                 if (!strcmp(town_info[creature_ptr->town_num].name, _("荒野", "wilderness")))
356                 {
357                         msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
358                         return;
359                 }
360
361                 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
362                 return;
363         }
364
365         if (!creature_ptr->current_floor_ptr->dun_level)
366         {
367                 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
368                 return;
369         }
370
371         if (creature_ptr->muta3 & MUT3_GOOD_LUCK)
372                 msg_print(do_cmd_feeling_text_lucky[creature_ptr->feeling]);
373         else if (IS_ECHIZEN(creature_ptr))
374                 msg_print(do_cmd_feeling_text_combat[creature_ptr->feeling]);
375         else
376                 msg_print(do_cmd_feeling_text[creature_ptr->feeling]);
377 }
378
379
380 /*
381  * Display the time and date
382  * @param creature_ptr プレーヤーへの参照ポインタ
383  * @return なし
384  */
385 void do_cmd_time(player_type *creature_ptr)
386 {
387         int day, hour, min;
388         extract_day_hour_min(creature_ptr, &day, &hour, &min);
389
390         char desc[1024];
391         strcpy(desc, _("変な時刻だ。", "It is a strange time."));
392
393         char day_buf[10];
394         if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
395         else strcpy(day_buf, "*****");
396
397         msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
398                 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
399
400         char buf[1024];
401         if (!randint0(10) || creature_ptr->image)
402         {
403                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
404         }
405         else
406         {
407                 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
408         }
409
410         FILE *fff;
411         fff = my_fopen(buf, "rt");
412
413         if (!fff) return;
414
415         int full = hour * 100 + min;
416         int start = 9999;
417         int end = -9999;
418         int num = 0;
419         while (!my_fgets(fff, buf, sizeof(buf)))
420         {
421                 if (!buf[0] || (buf[0] == '#')) continue;
422                 if (buf[1] != ':') continue;
423
424                 if (buf[0] == 'S')
425                 {
426                         start = atoi(buf + 2);
427                         end = start + 59;
428                         continue;
429                 }
430
431                 if (buf[0] == 'E')
432                 {
433                         end = atoi(buf + 2);
434                         continue;
435                 }
436
437                 if ((start > full) || (full > end)) continue;
438
439                 if (buf[0] == 'D')
440                 {
441                         num++;
442                         if (!randint0(num)) strcpy(desc, buf + 2);
443
444                         continue;
445                 }
446         }
447
448         msg_print(desc);
449         my_fclose(fff);
450 }