OSDN Git Service

For clarity, reworded English prompt for selecting the cards to keep in poker.
[hengband/hengband.git] / src / io / input-key-requester.c
1 #include "io/input-key-requester.h"
2 #include "cmd-io/cmd-menu-content-table.h"
3 #include "cmd-io/macro-util.h"
4 #include "core/asking-player.h" // todo 相互依存している、後で何とかする.
5 #include "game-option/input-options.h"
6 #include "inventory/inventory-slot-types.h"
7 #include "io/cursor.h"
8 #include "io/input-key-acceptor.h"
9 #include "main/sound-of-music.h"
10 #include "system/floor-type-definition.h" // todo 違和感、後で調査する.
11 #include "system/object-type-definition.h"
12 #include "term/screen-processor.h" // todo 相互依存している、後で何とかする.
13 #include "util/int-char-converter.h"
14 #include "util/quarks.h"
15 #include "util/string-processor.h"
16 #include "view/display-messages.h"
17 #include "window/main-window-util.h"
18
19 /*
20  * Keymaps for each "mode" associated with each keypress.
21  */
22 concptr keymap_act[KEYMAP_MODES][256];
23
24 bool use_menu;
25
26 s16b command_cmd; /* Current "Angband Command" */
27 COMMAND_ARG command_arg; /*!< 各種コマンドの汎用的な引数として扱う / Gives argument of current command */
28 COMMAND_NUM command_rep; /*!< 各種コマンドの汎用的なリピート数として扱う / Gives repetition of current command */
29 DIRECTION command_dir; /*!< 各種コマンドの汎用的な方向値処理として扱う/ Gives direction of current command */
30 s16b command_see; /* アイテム使用時等にリストを表示させるかどうか (ゲームオプションの他、様々なタイミングでONになったりOFFになったりする模様……) */
31 s16b command_wrk; /* アイテムの使用許可状況 (ex. 装備品のみ、床上もOK等) */
32 TERM_LEN command_gap = 999; /* アイテムの表示に使う (詳細未調査) */
33 s16b command_new; /* Command chaining from inven/equip view */
34
35 /*
36  * Hack -- special buffer to hold the action of the current keymap
37  */
38 static char request_command_buffer[256];
39
40 static char inkey_from_menu(player_type *player_ptr)
41 {
42     char cmd;
43     int basey, basex;
44     int num = 0, max_num, old_num = 0;
45     int menu = 0;
46     bool kisuu;
47
48     if (player_ptr->y - panel_row_min > 10)
49         basey = 2;
50     else
51         basey = 13;
52     basex = 15;
53
54     prt("", 0, 0);
55     screen_save();
56
57     floor_type *floor_ptr = player_ptr->current_floor_ptr;
58     while (TRUE) {
59         int i;
60         char sub_cmd;
61         concptr menu_name;
62         if (!menu)
63             old_num = num;
64         put_str("+----------------------------------------------------+", basey, basex);
65         put_str("|                                                    |", basey + 1, basex);
66         put_str("|                                                    |", basey + 2, basex);
67         put_str("|                                                    |", basey + 3, basex);
68         put_str("|                                                    |", basey + 4, basex);
69         put_str("|                                                    |", basey + 5, basex);
70         put_str("+----------------------------------------------------+", basey + 6, basex);
71
72         for (i = 0; i < 10; i++) {
73             int hoge;
74             if (!menu_info[menu][i].cmd)
75                 break;
76             menu_name = menu_info[menu][i].name;
77             for (hoge = 0;; hoge++) {
78                 if (!special_menu_info[hoge].name[0])
79                     break;
80                 if ((menu != special_menu_info[hoge].window) || (i != special_menu_info[hoge].number))
81                     continue;
82                 switch (special_menu_info[hoge].jouken) {
83                 case MENU_CLASS:
84                     if (player_ptr->pclass == special_menu_info[hoge].jouken_naiyou)
85                         menu_name = special_menu_info[hoge].name;
86                     break;
87                 case MENU_WILD:
88                     if (!floor_ptr->dun_level && !floor_ptr->inside_arena && !floor_ptr->inside_quest) {
89                         if ((byte)player_ptr->wild_mode == special_menu_info[hoge].jouken_naiyou)
90                             menu_name = special_menu_info[hoge].name;
91                     }
92                     break;
93                 default:
94                     break;
95                 }
96             }
97
98             put_str(menu_name, basey + 1 + i / 2, basex + 4 + (i % 2) * 24);
99         }
100
101         max_num = i;
102         kisuu = max_num % 2;
103         put_str(_("》", "> "), basey + 1 + num / 2, basex + 2 + (num % 2) * 24);
104
105         move_cursor_relative(player_ptr->y, player_ptr->x);
106         sub_cmd = inkey();
107         if ((sub_cmd == ' ') || (sub_cmd == 'x') || (sub_cmd == 'X') || (sub_cmd == '\r') || (sub_cmd == '\n')) {
108             if (menu_info[menu][num].fin) {
109                 cmd = menu_info[menu][num].cmd;
110                 use_menu = TRUE;
111                 break;
112             } else {
113                 menu = menu_info[menu][num].cmd;
114                 num = 0;
115                 basey += 2;
116                 basex += 8;
117             }
118         } else if ((sub_cmd == ESCAPE) || (sub_cmd == 'z') || (sub_cmd == 'Z') || (sub_cmd == '0')) {
119             if (!menu) {
120                 cmd = ESCAPE;
121                 break;
122             } else {
123                 menu = 0;
124                 num = old_num;
125                 basey -= 2;
126                 basex -= 8;
127                 screen_load();
128                 screen_save();
129             }
130         } else if ((sub_cmd == '2') || (sub_cmd == 'j') || (sub_cmd == 'J')) {
131             if (kisuu) {
132                 if (num % 2)
133                     num = (num + 2) % (max_num - 1);
134                 else
135                     num = (num + 2) % (max_num + 1);
136             } else
137                 num = (num + 2) % max_num;
138         } else if ((sub_cmd == '8') || (sub_cmd == 'k') || (sub_cmd == 'K')) {
139             if (kisuu) {
140                 if (num % 2)
141                     num = (num + max_num - 3) % (max_num - 1);
142                 else
143                     num = (num + max_num - 1) % (max_num + 1);
144             } else
145                 num = (num + max_num - 2) % max_num;
146         } else if ((sub_cmd == '4') || (sub_cmd == '6') || (sub_cmd == 'h') || (sub_cmd == 'H') || (sub_cmd == 'l') || (sub_cmd == 'L')) {
147             if ((num % 2) || (num == max_num - 1)) {
148                 num--;
149             } else if (num < max_num - 1) {
150                 num++;
151             }
152         }
153     }
154
155     screen_load();
156     if (!inkey_next)
157         inkey_next = "";
158
159     return (cmd);
160 }
161
162 /*
163  * Request a command from the user.
164  *
165  * Sets player_ptr->command_cmd, player_ptr->command_dir, player_ptr->command_rep,
166  * player_ptr->command_arg.  May modify player_ptr->command_new.
167  *
168  * Note that "caret" ("^") is treated specially, and is used to
169  * allow manual input of control characters.  This can be used
170  * on many machines to request repeated tunneling (Ctrl-H) and
171  * on the Macintosh to request "Control-Caret".
172  *
173  * Note that "backslash" is treated specially, and is used to bypass any
174  * keymap entry for the following character.  This is useful for macros.
175  *
176  * Note that this command is used both in the dungeon and in
177  * stores, and must be careful to work in both situations.
178  *
179  * Note that "player_ptr->command_new" may not work any more.
180  */
181 void request_command(player_type *player_ptr, int shopping)
182 {
183     s16b cmd;
184     int mode;
185
186     concptr act;
187
188 #ifdef JP
189     int caretcmd = 0;
190 #endif
191     if (rogue_like_commands) {
192         mode = KEYMAP_MODE_ROGUE;
193     } else {
194         mode = KEYMAP_MODE_ORIG;
195     }
196
197     command_cmd = 0;
198     command_arg = 0;
199     command_dir = 0;
200     use_menu = FALSE;
201
202     while (TRUE) {
203         if (command_new) {
204             msg_erase();
205             cmd = command_new;
206             command_new = 0;
207         } else {
208             msg_flag = FALSE;
209             num_more = 0;
210             inkey_flag = TRUE;
211             if (need_term_fresh()) {
212                 term_fresh();
213             }
214             cmd = inkey();
215             if (!shopping && command_menu && ((cmd == '\r') || (cmd == '\n') || (cmd == 'x') || (cmd == 'X')) && !keymap_act[mode][(byte)(cmd)])
216                 cmd = inkey_from_menu(player_ptr);
217         }
218
219         prt("", 0, 0);
220         if (cmd == '0') {
221             COMMAND_ARG old_arg = command_arg;
222             command_arg = 0;
223             prt(_("回数: ", "Count: "), 0, 0);
224             while (TRUE) {
225                 cmd = inkey();
226                 if ((cmd == 0x7F) || (cmd == KTRL('H'))) {
227                     command_arg = command_arg / 10;
228                     prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
229                 } else if (cmd >= '0' && cmd <= '9') {
230                     if (command_arg >= 1000) {
231                         bell();
232                         command_arg = 9999;
233                     } else {
234                         command_arg = command_arg * 10 + D2I(cmd);
235                     }
236
237                     prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
238                 } else {
239                     break;
240                 }
241             }
242
243             if (command_arg == 0) {
244                 command_arg = 99;
245                 prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
246             }
247
248             if (old_arg != 0) {
249                 command_arg = old_arg;
250                 prt(format(_("回数: %d", "Count: %d"), command_arg), 0, 0);
251             }
252
253             if ((cmd == ' ') || (cmd == '\n') || (cmd == '\r')) {
254                 if (!get_com(_("コマンド: ", "Command: "), (char *)&cmd, FALSE)) {
255                     command_arg = 0;
256                     continue;
257                 }
258             }
259         }
260
261         if (cmd == '\\') {
262             (void)get_com(_("コマンド: ", "Command: "), (char *)&cmd, FALSE);
263             if (!inkey_next)
264                 inkey_next = "";
265         }
266
267         if (cmd == '^') {
268             if (get_com(_("CTRL: ", "Control: "), (char *)&cmd, FALSE))
269                 cmd = KTRL(cmd);
270         }
271
272         act = keymap_act[mode][(byte)(cmd)];
273         if (act && !inkey_next) {
274             (void)strnfmt(request_command_buffer, 256, "%s", act);
275             inkey_next = request_command_buffer;
276             continue;
277         }
278
279         if (!cmd)
280             continue;
281
282         command_cmd = (byte)cmd;
283         break;
284     }
285
286     if (always_repeat && (command_arg <= 0)) {
287         if (angband_strchr("TBDoc+", (char)command_cmd)) {
288             command_arg = 99;
289         }
290     }
291
292     if (shopping == 1) {
293         switch (command_cmd) {
294         case 'p':
295             command_cmd = 'g';
296             break;
297
298         case 'm':
299             command_cmd = 'g';
300             break;
301
302         case 's':
303             command_cmd = 'd';
304             break;
305         }
306     }
307
308 #ifdef JP
309     for (int i = 0; i < 256; i++) {
310         concptr s;
311         if ((s = keymap_act[mode][i]) != NULL) {
312             if (*s == command_cmd && *(s + 1) == 0) {
313                 caretcmd = i;
314                 break;
315             }
316         }
317     }
318
319     if (!caretcmd)
320         caretcmd = command_cmd;
321 #endif
322
323     for (inventory_slot_type i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
324         object_type *o_ptr = &player_ptr->inventory_list[i];
325         if (!o_ptr->k_idx)
326             continue;
327
328         if (!o_ptr->inscription)
329             continue;
330
331         concptr s = quark_str(o_ptr->inscription);
332         s = angband_strchr(s, '^');
333         while (s) {
334 #ifdef JP
335             if ((s[1] == caretcmd) || (s[1] == '*'))
336 #else
337             if ((s[1] == command_cmd) || (s[1] == '*'))
338 #endif
339             {
340                 if (!get_check(_("本当ですか? ", "Are you sure? "))) {
341                     command_cmd = ' ';
342                 }
343             }
344
345             s = angband_strchr(s + 1, '^');
346         }
347     }
348
349     prt("", 0, 0);
350 }