OSDN Git Service

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