OSDN Git Service

[Refactor] #40534 Separated flavor-describer.c/h from object-flavor.c/h
[hengband/hengband.git] / src / cmd-visual / cmd-visuals.c
1 #include "cmd-visual/cmd-visuals.h"
2 #include "cmd-visual/cmd-draw.h"
3 #include "core/asking-player.h"
4 #include "core/visuals-reseter.h"
5 #include "flavor/flavor-describer.h"
6 #include "flavor/object-flavor-types.h"
7 #include "game-option/special-options.h"
8 #include "io/files-util.h"
9 #include "io/input-key-acceptor.h"
10 #include "io/read-pref-file.h"
11 #include "knowledge/knowledge-features.h"
12 #include "knowledge/knowledge-items.h"
13 #include "knowledge/knowledge-monsters.h"
14 #include "knowledge/lighting-level-table.h"
15 #include "main/sound-of-music.h"
16 #include "monster-race/monster-race.h"
17 #include "object/object-flavor.h"
18 #include "object/object-generator.h"
19 #include "object/object-kind.h"
20 #include "term/screen-processor.h"
21 #include "term/term-color-types.h"
22 #include "util/angband-files.h"
23 #include "util/int-char-converter.h"
24 #include "view/display-messages.h"
25
26 /*!
27  * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
28  * @param i 指定対象となるキャラクタコード
29  * @param num 指定されたビジュアルIDを返す参照ポインタ
30  * @param max ビジュアルIDの最大数
31  * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
32  */
33 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
34 {
35     if (iscntrl(i)) {
36         char str[10] = "";
37         sprintf(str, "%d", *num);
38         if (!get_string(format("Input new number(0-%d): ", max - 1), str, 4))
39             return FALSE;
40
41         IDX tmp = (IDX)strtol(str, NULL, 0);
42         if (tmp >= 0 && tmp < max)
43             *num = tmp;
44     } else if (isupper(i))
45         *num = (*num + max - 1) % max;
46     else
47         *num = (*num + 1) % max;
48
49     return TRUE;
50 }
51
52 /*!
53  * @brief キャラクタの変更メニュー表示
54  * @param choice_msg 選択メッセージ
55  * @return なし
56  */
57 static void print_visuals_menu(concptr choice_msg)
58 {
59     prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
60     prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
61     prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
62     prt(_("(2) アイテムの   色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
63     prt(_("(3) 地形の       色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
64     prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
65     prt(_("(5) アイテムの   色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
66     prt(_("(6) 地形の       色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
67     prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
68     prt(_("(8) アイテムの   色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
69     prt(_("(9) 地形の       色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
70     prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
71     prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
72 }
73
74 /*
75  * Interact with "visuals"
76  */
77 void do_cmd_visuals(player_type *creature_ptr, void (*process_autopick_file_command)(char *))
78 {
79     FILE *auto_dump_stream;
80     char tmp[160];
81     char buf[1024];
82     bool need_redraw = FALSE;
83     concptr empty_symbol = "<< ? >>";
84     if (use_bigtile)
85         empty_symbol = "<< ?? >>";
86
87     screen_save();
88     while (TRUE) {
89         Term_clear();
90         print_visuals_menu(NULL);
91         int i = inkey();
92         if (i == ESCAPE)
93             break;
94
95         switch (i) {
96         case '0': {
97             prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
98             prt(_("ファイル: ", "File: "), 17, 0);
99             sprintf(tmp, "%s.prf", creature_ptr->base_name);
100             if (!askfor(tmp, 70))
101                 continue;
102
103             (void)process_pref_file(creature_ptr, tmp, process_autopick_file_command);
104             need_redraw = TRUE;
105             break;
106         }
107         case '1': {
108             static concptr mark = "Monster attr/chars";
109             prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
110             prt(_("ファイル: ", "File: "), 17, 0);
111             sprintf(tmp, "%s.prf", creature_ptr->base_name);
112             if (!askfor(tmp, 70))
113                 continue;
114
115             path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
116             if (!open_auto_dump(&auto_dump_stream, buf, mark))
117                 continue;
118
119             auto_dump_printf(auto_dump_stream, _("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
120             for (i = 0; i < max_r_idx; i++) {
121                 monster_race *r_ptr = &r_info[i];
122                 if (!r_ptr->name)
123                     continue;
124
125                 auto_dump_printf(auto_dump_stream, "# %s\n", (r_name + r_ptr->name));
126                 auto_dump_printf(auto_dump_stream, "R:%d:0x%02X/0x%02X\n\n", i, (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
127             }
128
129             close_auto_dump(&auto_dump_stream, mark);
130             msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
131             break;
132         }
133         case '2': {
134             static concptr mark = "Object attr/chars";
135             prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
136             prt(_("ファイル: ", "File: "), 17, 0);
137             sprintf(tmp, "%s.prf", creature_ptr->base_name);
138             if (!askfor(tmp, 70))
139                 continue;
140
141             path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
142             if (!open_auto_dump(&auto_dump_stream, buf, mark))
143                 continue;
144
145             auto_dump_printf(auto_dump_stream, _("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
146             for (KIND_OBJECT_IDX k_idx = 0; k_idx < max_k_idx; k_idx++) {
147                 GAME_TEXT o_name[MAX_NLEN];
148                 object_kind *k_ptr = &k_info[k_idx];
149                 if (!k_ptr->name)
150                     continue;
151
152                 if (!k_ptr->flavor) {
153                     strip_name(o_name, k_idx);
154                 } else {
155                     object_type forge;
156                     object_prep(creature_ptr, &forge, k_idx);
157                     describe_flavor(creature_ptr, o_name, &forge, OD_FORCE_FLAVOR);
158                 }
159
160                 auto_dump_printf(auto_dump_stream, "# %s\n", o_name);
161                 auto_dump_printf(auto_dump_stream, "K:%d:0x%02X/0x%02X\n\n", (int)k_idx, (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
162             }
163
164             close_auto_dump(&auto_dump_stream, mark);
165             msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
166             break;
167         }
168         case '3': {
169             static concptr mark = "Feature attr/chars";
170             prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
171             prt(_("ファイル: ", "File: "), 17, 0);
172             sprintf(tmp, "%s.prf", creature_ptr->base_name);
173             if (!askfor(tmp, 70))
174                 continue;
175
176             path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
177             if (!open_auto_dump(&auto_dump_stream, buf, mark))
178                 continue;
179
180             auto_dump_printf(auto_dump_stream, _("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
181             for (i = 0; i < max_f_idx; i++) {
182                 feature_type *f_ptr = &f_info[i];
183                 if (!f_ptr->name)
184                     continue;
185                 if (f_ptr->mimic != i)
186                     continue;
187
188                 auto_dump_printf(auto_dump_stream, "# %s\n", (f_name + f_ptr->name));
189                 auto_dump_printf(auto_dump_stream, "F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i, (byte)(f_ptr->x_attr[F_LIT_STANDARD]),
190                     (byte)(f_ptr->x_char[F_LIT_STANDARD]), (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
191                     (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
192             }
193
194             close_auto_dump(&auto_dump_stream, mark);
195             msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
196             break;
197         }
198         case '4': {
199             static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
200             static MONRACE_IDX r = 0;
201             prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
202             while (TRUE) {
203                 monster_race *r_ptr = &r_info[r];
204                 int c;
205                 IDX t;
206
207                 TERM_COLOR da = r_ptr->d_attr;
208                 byte dc = r_ptr->d_char;
209                 TERM_COLOR ca = r_ptr->x_attr;
210                 byte cc = r_ptr->x_char;
211
212                 Term_putstr(5, 17, -1, TERM_WHITE, format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
213                 Term_putstr(10, 19, -1, TERM_WHITE, format(_("初期値  色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
214                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
215                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
216                 Term_putstr(10, 20, -1, TERM_WHITE, format(_("現在値  色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
217                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
218                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
219                 Term_putstr(0, 22, -1, TERM_WHITE, _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
220                 i = inkey();
221                 if (i == ESCAPE)
222                     break;
223
224                 if (iscntrl(i))
225                     c = 'a' + i - KTRL('A');
226                 else if (isupper(i))
227                     c = 'a' + i - 'A';
228                 else
229                     c = i;
230
231                 switch (c) {
232                 case 'n': {
233                     IDX prev_r = r;
234                     do {
235                         if (!cmd_visuals_aux(i, &r, max_r_idx)) {
236                             r = prev_r;
237                             break;
238                         }
239                     } while (!r_info[r].name);
240                 }
241
242                 break;
243                 case 'a':
244                     t = (int)r_ptr->x_attr;
245                     (void)cmd_visuals_aux(i, &t, 256);
246                     r_ptr->x_attr = (byte)t;
247                     need_redraw = TRUE;
248                     break;
249                 case 'c':
250                     t = (int)r_ptr->x_char;
251                     (void)cmd_visuals_aux(i, &t, 256);
252                     r_ptr->x_char = (byte)t;
253                     need_redraw = TRUE;
254                     break;
255                 case 'v':
256                     do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, r);
257                     Term_clear();
258                     print_visuals_menu(choice_msg);
259                     break;
260                 }
261             }
262
263             break;
264         }
265         case '5': {
266             static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
267             static IDX k = 0;
268             prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
269             while (TRUE) {
270                 object_kind *k_ptr = &k_info[k];
271                 int c;
272                 IDX t;
273
274                 TERM_COLOR da = k_ptr->d_attr;
275                 SYMBOL_CODE dc = k_ptr->d_char;
276                 TERM_COLOR ca = k_ptr->x_attr;
277                 SYMBOL_CODE cc = k_ptr->x_char;
278
279                 Term_putstr(5, 17, -1, TERM_WHITE,
280                     format(
281                         _("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"), k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
282                 Term_putstr(10, 19, -1, TERM_WHITE, format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
283                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
284                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
285                 Term_putstr(10, 20, -1, TERM_WHITE, format(_("現在値  色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
286                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
287                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
288                 Term_putstr(0, 22, -1, TERM_WHITE, _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
289
290                 i = inkey();
291                 if (i == ESCAPE)
292                     break;
293
294                 if (iscntrl(i))
295                     c = 'a' + i - KTRL('A');
296                 else if (isupper(i))
297                     c = 'a' + i - 'A';
298                 else
299                     c = i;
300
301                 switch (c) {
302                 case 'n': {
303                     IDX prev_k = k;
304                     do {
305                         if (!cmd_visuals_aux(i, &k, max_k_idx)) {
306                             k = prev_k;
307                             break;
308                         }
309                     } while (!k_info[k].name);
310                 }
311
312                 break;
313                 case 'a':
314                     t = (int)k_ptr->x_attr;
315                     (void)cmd_visuals_aux(i, &t, 256);
316                     k_ptr->x_attr = (byte)t;
317                     need_redraw = TRUE;
318                     break;
319                 case 'c':
320                     t = (int)k_ptr->x_char;
321                     (void)cmd_visuals_aux(i, &t, 256);
322                     k_ptr->x_char = (byte)t;
323                     need_redraw = TRUE;
324                     break;
325                 case 'v':
326                     do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, k);
327                     Term_clear();
328                     print_visuals_menu(choice_msg);
329                     break;
330                 }
331             }
332
333             break;
334         }
335         case '6': {
336             static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
337             static IDX f = 0;
338             static IDX lighting_level = F_LIT_STANDARD;
339             prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
340             while (TRUE) {
341                 feature_type *f_ptr = &f_info[f];
342                 int c;
343                 IDX t;
344
345                 TERM_COLOR da = f_ptr->d_attr[lighting_level];
346                 byte dc = f_ptr->d_char[lighting_level];
347                 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
348                 byte cc = f_ptr->x_char[lighting_level];
349
350                 prt("", 17, 5);
351                 Term_putstr(5, 17, -1, TERM_WHITE,
352                     format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"), f, (f_name + f_ptr->name),
353                         lighting_level_str[lighting_level]));
354                 Term_putstr(10, 19, -1, TERM_WHITE, format(_("初期値  色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
355                 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
356                 Term_queue_bigchar(43, 19, da, dc, 0, 0);
357                 Term_putstr(10, 20, -1, TERM_WHITE, format(_("現在値  色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
358                 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
359                 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
360                 Term_putstr(0, 22, -1, TERM_WHITE,
361                     _("コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): "));
362
363                 i = inkey();
364                 if (i == ESCAPE)
365                     break;
366
367                 if (iscntrl(i))
368                     c = 'a' + i - KTRL('A');
369                 else if (isupper(i))
370                     c = 'a' + i - 'A';
371                 else
372                     c = i;
373
374                 switch (c) {
375                 case 'n': {
376                     IDX prev_f = f;
377                     do {
378                         if (!cmd_visuals_aux(i, &f, max_f_idx)) {
379                             f = prev_f;
380                             break;
381                         }
382                     } while (!f_info[f].name || (f_info[f].mimic != f));
383                 }
384
385                 break;
386                 case 'a':
387                     t = (int)f_ptr->x_attr[lighting_level];
388                     (void)cmd_visuals_aux(i, &t, 256);
389                     f_ptr->x_attr[lighting_level] = (byte)t;
390                     need_redraw = TRUE;
391                     break;
392                 case 'c':
393                     t = (int)f_ptr->x_char[lighting_level];
394                     (void)cmd_visuals_aux(i, &t, 256);
395                     f_ptr->x_char[lighting_level] = (byte)t;
396                     need_redraw = TRUE;
397                     break;
398                 case 'l':
399                     (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
400                     break;
401                 case 'd':
402                     apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
403                     need_redraw = TRUE;
404                     break;
405                 case 'v':
406                     do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
407                     Term_clear();
408                     print_visuals_menu(choice_msg);
409                     break;
410                 }
411             }
412
413             break;
414         }
415         case '7':
416             do_cmd_knowledge_monsters(creature_ptr, &need_redraw, TRUE, -1);
417             break;
418         case '8':
419             do_cmd_knowledge_objects(creature_ptr, &need_redraw, TRUE, -1);
420             break;
421         case '9': {
422             IDX lighting_level = F_LIT_STANDARD;
423             do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
424             break;
425         }
426         case 'R':
427         case 'r':
428             reset_visuals(creature_ptr, process_autopick_file_command);
429             msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
430             need_redraw = TRUE;
431             break;
432         default:
433             bell();
434             break;
435         }
436
437         msg_erase();
438     }
439
440     screen_load();
441     if (need_redraw)
442         do_cmd_redraw(creature_ptr);
443 }