OSDN Git Service

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