OSDN Git Service

[Refactor] #38862 Moved player-*.c/h to player/ except for player-inventory.c/h
[hengband/hengband.git] / src / io / input-key-processor.c
1 /*!
2  * todo Ctrl+C がShift+Q に認識されている。仕様の可能性も高いが要確認
3  * @brief キー入力に応じてゲーム内コマンドを実行する
4  * @date 2020/05/10
5  * @author Hourier
6  */
7
8 #include "angband.h"
9 #include "io/input-key-processor.h"
10 #include "world/world.h"
11 #include "core/special-internal-keys.h"
12 #include "dungeon/dungeon.h"
13 #include "snipe.h"
14 #include "autopick/autopick-pref-processor.h"
15 #include "market/store-util.h"
16 #include "main/sound-definitions-table.h"
17 #include "io/write-diary.h"
18 #include "player-inventory.h"
19 #include "player/player-effects.h"
20 #include "market/store.h" // do_cmd_store() がある。後で移設する.
21 #include "quest.h" // do_cmd_quest() がある。後で移設する.
22 #include "wild.h"
23 #include "spells-object.h"
24 #include "mind.h" // do_cmd_mind_browse() がある。後で移設する.
25 #include "monster-spell.h" // do_cmd_cast_learned() がある。後で移設する.
26 #include "racial.h" // do_cmd_racial_power() がある。ファイル名変更?.
27 #include "view/display-main-window.h"
28 #include "knowledge/knowledge-autopick.h"
29 #include "knowledge/knowledge-quests.h"
30 #include "chuukei.h"
31 #include "player/player-move.h" // do_cmd_travel() がある。後で移設する.
32 #include "files.h"
33
34 #include "cmd/cmd-activate.h"
35 #include "cmd/cmd-autopick.h"
36 #include "cmd/cmd-diary.h"
37 #include "cmd/cmd-draw.h"
38 #include "cmd/cmd-dump.h"
39 #include "cmd/cmd-process-screen.h"
40 #include "cmd/cmd-eat.h"
41 #include "cmd/cmd-help.h"
42 #include "cmd/cmd-hissatsu.h"
43 #include "cmd/cmd-item.h"
44 #include "cmd/cmd-knowledge.h"
45 #include "cmd/cmd-magiceat.h"
46 #include "cmd/cmd-mane.h"
47 #include "cmd/cmd-macro.h"
48 #include "cmd/cmd-quaff.h"
49 #include "cmd/cmd-read.h"
50 #include "cmd/cmd-save.h"
51 #include "cmd/cmd-smith.h"
52 #include "cmd-spell.h"
53 #include "cmd/cmd-usestaff.h"
54 #include "cmd/cmd-zaprod.h"
55 #include "cmd/cmd-zapwand.h"
56 #include "cmd/cmd-pet.h"
57 #include "cmd/cmd-basic.h"
58 #include "cmd/cmd-visuals.h"
59 #include "wizard/wizard-spoiler.h"
60 #include "wizard/wizard-special-process.h"
61
62 // todo command-processor.h と util.h が相互依存している。後で別な場所に移す.
63 COMMAND_CODE now_message;
64
65 /*!
66  * @brief ウィザードモードへの導入処理
67  * / Verify use of "wizard" mode
68  * @param player_ptr プレーヤーへの参照ポインタ
69  * @return 実際にウィザードモードへ移行したらTRUEを返す。
70  */
71 bool enter_wizard_mode(player_type* player_ptr)
72 {
73     if (!current_world_ptr->noscore) {
74         if (!allow_debug_opts || arg_wizard) {
75             msg_print(_("ウィザードモードは許可されていません。 ", "Wizard mode is not permitted."));
76             return FALSE;
77         }
78
79         msg_print(_("ウィザードモードはデバッグと実験のためのモードです。 ", "Wizard mode is for debugging and experimenting."));
80         msg_print(_("一度ウィザードモードに入るとスコアは記録されません。", "The game will not be scored if you enter wizard mode."));
81         msg_print(NULL);
82         if (!get_check(_("本当にウィザードモードに入りたいのですか? ", "Are you sure you want to enter wizard mode? "))) {
83             return FALSE;
84         }
85
86         exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, _("ウィザードモードに突入してスコアを残せなくなった。", "gave up recording score to enter wizard mode."));
87         current_world_ptr->noscore |= 0x0002;
88     }
89
90     return TRUE;
91 }
92
93 /*!
94  * @brief デバッグコマンドへの導入処理
95  * / Verify use of "debug" commands
96  * @param player_ptr プレーヤーへの参照ポインタ
97  * @return 実際にデバッグコマンドへ移行したらTRUEを返す。
98  */
99 static bool enter_debug_mode(player_type* player_ptr)
100 {
101     if (!current_world_ptr->noscore) {
102         if (!allow_debug_opts) {
103             msg_print(_("デバッグコマンドは許可されていません。 ", "Use of debug command is not permitted."));
104             return FALSE;
105         }
106
107         msg_print(_("デバッグ・コマンドはデバッグと実験のためのコマンドです。 ", "The debug commands are for debugging and experimenting."));
108         msg_print(_("デバッグ・コマンドを使うとスコアは記録されません。", "The game will not be scored if you use debug commands."));
109         msg_print(NULL);
110         if (!get_check(_("本当にデバッグ・コマンドを使いますか? ", "Are you sure you want to use debug commands? "))) {
111             return FALSE;
112         }
113
114         exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, _("デバッグモードに突入してスコアを残せなくなった。", "gave up sending score to use debug commands."));
115         current_world_ptr->noscore |= 0x0008;
116     }
117
118     return TRUE;
119 }
120
121 /*!
122  * @brief プレイヤーから受けた入力コマンドの分岐処理。
123  * / Parse and execute the current command Give "Warning" on illegal commands.
124  * @todo Make some "blocks"
125  * @return なし
126  */
127 void process_command(player_type* creature_ptr)
128 {
129     COMMAND_CODE old_now_message = now_message;
130     repeat_check();
131     now_message = 0;
132     if ((creature_ptr->pclass == CLASS_SNIPER) && (creature_ptr->concent))
133         creature_ptr->reset_concent = TRUE;
134
135     floor_type* floor_ptr = creature_ptr->current_floor_ptr;
136     switch (command_cmd) {
137     case ESCAPE:
138     case ' ':
139     case '\r':
140     case '\n': {
141         /* Ignore */
142         break;
143     }
144     case KTRL('W'): {
145         if (current_world_ptr->wizard) {
146             current_world_ptr->wizard = FALSE;
147             msg_print(_("ウィザードモード解除。", "Wizard mode off."));
148         } else if (enter_wizard_mode(creature_ptr)) {
149             current_world_ptr->wizard = TRUE;
150             msg_print(_("ウィザードモード突入。", "Wizard mode on."));
151         }
152
153         creature_ptr->update |= (PU_MONSTERS);
154         creature_ptr->redraw |= (PR_TITLE);
155         break;
156     }
157     case KTRL('A'): {
158         if (enter_debug_mode(creature_ptr)) {
159             do_cmd_debug(creature_ptr);
160         }
161
162         break;
163     }
164     case 'w': {
165         if (!creature_ptr->wild_mode)
166             do_cmd_wield(creature_ptr);
167
168         break;
169     }
170     case 't': {
171         if (!creature_ptr->wild_mode)
172             do_cmd_takeoff(creature_ptr);
173
174         break;
175     }
176     case 'd': {
177         if (!creature_ptr->wild_mode)
178             do_cmd_drop(creature_ptr);
179
180         break;
181     }
182     case 'k': {
183         do_cmd_destroy(creature_ptr);
184         break;
185     }
186     case 'e': {
187         do_cmd_equip(creature_ptr);
188         break;
189     }
190     case 'i': {
191         do_cmd_inven(creature_ptr);
192         break;
193     }
194     case 'I': {
195         do_cmd_observe(creature_ptr);
196         break;
197     }
198
199     case KTRL('I'): {
200         toggle_inventory_equipment(creature_ptr);
201         break;
202     }
203     case '+': {
204         if (!creature_ptr->wild_mode)
205             do_cmd_alter(creature_ptr);
206
207         break;
208     }
209     case 'T': {
210         if (!creature_ptr->wild_mode)
211             do_cmd_tunnel(creature_ptr);
212
213         break;
214     }
215     case ';': {
216         do_cmd_walk(creature_ptr, FALSE);
217         break;
218     }
219     case '-': {
220         do_cmd_walk(creature_ptr, TRUE);
221         break;
222     }
223     case '.': {
224         if (!creature_ptr->wild_mode)
225             do_cmd_run(creature_ptr);
226
227         break;
228     }
229     case ',': {
230         do_cmd_stay(creature_ptr, always_pickup);
231         break;
232     }
233     case 'g': {
234         do_cmd_stay(creature_ptr, !always_pickup);
235         break;
236     }
237     case 'R': {
238         do_cmd_rest(creature_ptr);
239         break;
240     }
241     case 's': {
242         do_cmd_search(creature_ptr);
243         break;
244     }
245     case 'S': {
246         if (creature_ptr->action == ACTION_SEARCH)
247             set_action(creature_ptr, ACTION_NONE);
248         else
249             set_action(creature_ptr, ACTION_SEARCH);
250
251         break;
252     }
253     case SPECIAL_KEY_STORE: {
254         do_cmd_store(creature_ptr);
255         break;
256     }
257     case SPECIAL_KEY_BUILDING: {
258         do_cmd_bldg(creature_ptr);
259         break;
260     }
261     case SPECIAL_KEY_QUEST: {
262         do_cmd_quest(creature_ptr);
263         break;
264     }
265     case '<': {
266         if (!creature_ptr->wild_mode && !floor_ptr->dun_level && !floor_ptr->inside_arena && !floor_ptr->inside_quest) {
267             if (vanilla_town)
268                 break;
269
270             if (creature_ptr->ambush_flag) {
271                 msg_print(_("襲撃から逃げるにはマップの端まで移動しなければならない。", "To flee the ambush you have to reach the edge of the map."));
272                 break;
273             }
274
275             if (creature_ptr->food < PY_FOOD_WEAK) {
276                 msg_print(_("その前に食事をとらないと。", "You must eat something here."));
277                 break;
278             }
279
280             change_wild_mode(creature_ptr, FALSE);
281         } else
282             do_cmd_go_up(creature_ptr);
283
284         break;
285     }
286     case '>': {
287         if (creature_ptr->wild_mode)
288             change_wild_mode(creature_ptr, FALSE);
289         else
290             do_cmd_go_down(creature_ptr);
291
292         break;
293     }
294     case 'o': {
295         do_cmd_open(creature_ptr);
296         break;
297     }
298     case 'c': {
299         do_cmd_close(creature_ptr);
300         break;
301     }
302     case 'j': {
303         do_cmd_spike(creature_ptr);
304         break;
305     }
306     case 'B': {
307         do_cmd_bash(creature_ptr);
308         break;
309     }
310     case 'D': {
311         do_cmd_disarm(creature_ptr);
312         break;
313     }
314     case 'G': {
315         if ((creature_ptr->pclass == CLASS_SORCERER) || (creature_ptr->pclass == CLASS_RED_MAGE))
316             msg_print(_("呪文を学習する必要はない!", "You don't have to learn spells!"));
317         else if (creature_ptr->pclass == CLASS_SAMURAI)
318             do_cmd_gain_hissatsu(creature_ptr);
319         else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
320             import_magic_device(creature_ptr);
321         else
322             do_cmd_study(creature_ptr);
323
324         break;
325     }
326     case 'b': {
327         if ((creature_ptr->pclass == CLASS_MINDCRAFTER) || (creature_ptr->pclass == CLASS_BERSERKER) || (creature_ptr->pclass == CLASS_NINJA) || (creature_ptr->pclass == CLASS_MIRROR_MASTER))
328             do_cmd_mind_browse(creature_ptr);
329         else if (creature_ptr->pclass == CLASS_SMITH)
330             do_cmd_kaji(creature_ptr, TRUE);
331         else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
332             do_cmd_magic_eater(creature_ptr, TRUE, FALSE);
333         else if (creature_ptr->pclass == CLASS_SNIPER)
334             do_cmd_snipe_browse(creature_ptr);
335         else
336             do_cmd_browse(creature_ptr);
337
338         break;
339     }
340     case 'm': {
341         if (!creature_ptr->wild_mode) {
342             if ((creature_ptr->pclass == CLASS_WARRIOR) || (creature_ptr->pclass == CLASS_ARCHER) || (creature_ptr->pclass == CLASS_CAVALRY)) {
343                 msg_print(_("呪文を唱えられない!", "You cannot cast spells!"));
344             } else if (floor_ptr->dun_level && (d_info[creature_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && (creature_ptr->pclass != CLASS_BERSERKER) && (creature_ptr->pclass != CLASS_SMITH)) {
345                 msg_print(_("ダンジョンが魔法を吸収した!", "The dungeon absorbs all attempted magic!"));
346                 msg_print(NULL);
347             } else if (creature_ptr->anti_magic && (creature_ptr->pclass != CLASS_BERSERKER) && (creature_ptr->pclass != CLASS_SMITH)) {
348                 concptr which_power = _("魔法", "magic");
349                 if (creature_ptr->pclass == CLASS_MINDCRAFTER)
350                     which_power = _("超能力", "psionic powers");
351                 else if (creature_ptr->pclass == CLASS_IMITATOR)
352                     which_power = _("ものまね", "imitation");
353                 else if (creature_ptr->pclass == CLASS_SAMURAI)
354                     which_power = _("必殺剣", "hissatsu");
355                 else if (creature_ptr->pclass == CLASS_MIRROR_MASTER)
356                     which_power = _("鏡魔法", "mirror magic");
357                 else if (creature_ptr->pclass == CLASS_NINJA)
358                     which_power = _("忍術", "ninjutsu");
359                 else if (mp_ptr->spell_book == TV_LIFE_BOOK)
360                     which_power = _("祈り", "prayer");
361
362                 msg_format(_("反魔法バリアが%sを邪魔した!", "An anti-magic shell disrupts your %s!"), which_power);
363                 free_turn(creature_ptr);
364             } else if (creature_ptr->shero && (creature_ptr->pclass != CLASS_BERSERKER)) {
365                 msg_format(_("狂戦士化していて頭が回らない!", "You cannot think directly!"));
366                 free_turn(creature_ptr);
367             } else {
368                 if ((creature_ptr->pclass == CLASS_MINDCRAFTER) || (creature_ptr->pclass == CLASS_BERSERKER) || (creature_ptr->pclass == CLASS_NINJA) || (creature_ptr->pclass == CLASS_MIRROR_MASTER))
369                     do_cmd_mind(creature_ptr);
370                 else if (creature_ptr->pclass == CLASS_IMITATOR)
371                     do_cmd_mane(creature_ptr, FALSE);
372                 else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
373                     do_cmd_magic_eater(creature_ptr, FALSE, FALSE);
374                 else if (creature_ptr->pclass == CLASS_SAMURAI)
375                     do_cmd_hissatsu(creature_ptr);
376                 else if (creature_ptr->pclass == CLASS_BLUE_MAGE)
377                     do_cmd_cast_learned(creature_ptr);
378                 else if (creature_ptr->pclass == CLASS_SMITH)
379                     do_cmd_kaji(creature_ptr, FALSE);
380                 else if (creature_ptr->pclass == CLASS_SNIPER)
381                     do_cmd_snipe(creature_ptr);
382                 else
383                     do_cmd_cast(creature_ptr);
384             }
385         }
386
387         break;
388     }
389     case 'p': {
390         do_cmd_pet(creature_ptr);
391         break;
392     }
393     case '{': {
394         do_cmd_inscribe(creature_ptr);
395         break;
396     }
397     case '}': {
398         do_cmd_uninscribe(creature_ptr);
399         break;
400     }
401     case 'A': {
402         do_cmd_activate(creature_ptr);
403         break;
404     }
405     case 'E': {
406         do_cmd_eat_food(creature_ptr);
407         break;
408     }
409     case 'F': {
410         do_cmd_refill(creature_ptr);
411         break;
412     }
413     case 'f': {
414         do_cmd_fire(creature_ptr, SP_NONE);
415         break;
416     }
417     case 'v': {
418         do_cmd_throw(creature_ptr, 1, FALSE, -1);
419         break;
420     }
421     case 'a': {
422         do_cmd_aim_wand(creature_ptr);
423         break;
424     }
425     case 'z': {
426         if (use_command && rogue_like_commands) {
427             do_cmd_use(creature_ptr);
428         } else {
429             do_cmd_zap_rod(creature_ptr);
430         }
431
432         break;
433     }
434     case 'q': {
435         do_cmd_quaff_potion(creature_ptr);
436         break;
437     }
438     case 'r': {
439         do_cmd_read_scroll(creature_ptr);
440         break;
441     }
442     case 'u': {
443         if (use_command && !rogue_like_commands)
444             do_cmd_use(creature_ptr);
445         else
446             do_cmd_use_staff(creature_ptr);
447
448         break;
449     }
450     case 'U': {
451         do_cmd_racial_power(creature_ptr);
452         break;
453     }
454     case 'M': {
455         do_cmd_view_map(creature_ptr);
456         break;
457     }
458     case 'L': {
459         do_cmd_locate(creature_ptr);
460         break;
461     }
462     case 'l': {
463         do_cmd_look(creature_ptr);
464         break;
465     }
466     case '*': {
467         do_cmd_target(creature_ptr);
468         break;
469     }
470     case '?': {
471         do_cmd_help(creature_ptr);
472         break;
473     }
474     case '/': {
475         do_cmd_query_symbol(creature_ptr);
476         break;
477     }
478     case 'C': {
479         do_cmd_player_status(creature_ptr);
480         break;
481     }
482     case '!': {
483         (void)Term_user(0);
484         break;
485     }
486     case '"': {
487         do_cmd_pref(creature_ptr);
488         break;
489     }
490     case '$': {
491         do_cmd_reload_autopick(creature_ptr);
492         break;
493     }
494     case '_': {
495         do_cmd_edit_autopick(creature_ptr);
496         break;
497     }
498     case '@': {
499         do_cmd_macros(creature_ptr, process_autopick_file_command);
500         break;
501     }
502     case '%': {
503         do_cmd_visuals(creature_ptr, process_autopick_file_command);
504         do_cmd_redraw(creature_ptr);
505         break;
506     }
507     case '&': {
508         do_cmd_colors(creature_ptr, process_autopick_file_command);
509         do_cmd_redraw(creature_ptr);
510         break;
511     }
512     case '=': {
513         do_cmd_options();
514         (void)combine_and_reorder_home(STORE_HOME);
515         do_cmd_redraw(creature_ptr);
516         break;
517     }
518     case ':': {
519         do_cmd_note();
520         break;
521     }
522     case 'V': {
523         do_cmd_version();
524         break;
525     }
526     case KTRL('F'): {
527         do_cmd_feeling(creature_ptr);
528         break;
529     }
530     case KTRL('O'): {
531         do_cmd_message_one();
532         break;
533     }
534     case KTRL('P'): {
535         do_cmd_messages(old_now_message);
536         break;
537     }
538     case KTRL('Q'): {
539         do_cmd_checkquest(creature_ptr);
540         break;
541     }
542     case KTRL('R'): {
543         now_message = old_now_message;
544         do_cmd_redraw(creature_ptr);
545         break;
546     }
547     case KTRL('S'): {
548         do_cmd_save_game(creature_ptr, FALSE);
549         break;
550     }
551     case KTRL('T'): {
552         do_cmd_time(creature_ptr);
553         break;
554     }
555     case KTRL('X'):
556     case SPECIAL_KEY_QUIT: {
557         do_cmd_save_and_exit(creature_ptr);
558         break;
559     }
560     case 'Q': {
561         do_cmd_suicide(creature_ptr);
562         break;
563     }
564     case '|': {
565         do_cmd_diary(creature_ptr);
566         break;
567     }
568     case '~': {
569         do_cmd_knowledge(creature_ptr);
570         break;
571     }
572     case '(': {
573         do_cmd_load_screen();
574         break;
575     }
576     case ')': {
577         do_cmd_save_screen(creature_ptr, process_autopick_file_command);
578         break;
579     }
580     case ']': {
581         prepare_movie_hooks();
582         break;
583     }
584     case KTRL('V'): {
585         spoil_random_artifact(creature_ptr, "randifact.txt");
586         break;
587     }
588     case '`': {
589         if (!creature_ptr->wild_mode)
590             do_cmd_travel(creature_ptr);
591         if (creature_ptr->special_defense & KATA_MUSOU) {
592             set_action(creature_ptr, ACTION_NONE);
593         }
594
595         break;
596     }
597     default: {
598         if (flush_failure)
599             flush();
600         if (one_in_(2)) {
601             char error_m[1024];
602             sound(SOUND_ILLEGAL);
603             if (!get_rnd_line(_("error_j.txt", "error.txt"), 0, error_m))
604                 msg_print(error_m);
605         } else {
606             prt(_(" '?' でヘルプが表示されます。", "Type '?' for help."), 0, 0);
607         }
608
609         break;
610     }
611     }
612
613     if (!creature_ptr->energy_use && !now_message)
614         now_message = old_now_message;
615 }