OSDN Git Service

[Refactor] #963 Changed player-energy.h from the collective of function decleration...
[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-smith.h"
43 #include "cmd-item/cmd-throw.h"
44 #include "cmd-item/cmd-usestaff.h"
45 #include "cmd-item/cmd-zaprod.h"
46 #include "cmd-item/cmd-zapwand.h"
47 #include "cmd-visual/cmd-draw.h"
48 #include "cmd-visual/cmd-map.h"
49 #include "cmd-visual/cmd-visuals.h"
50 #include "core/asking-player.h"
51 #include "core/player-redraw-types.h"
52 #include "core/player-update-types.h"
53 #include "core/special-internal-keys.h"
54 #include "dungeon/dungeon-flag-types.h"
55 #include "dungeon/dungeon.h"
56 #include "dungeon/quest.h" //!< @do_cmd_quest() がある。後で移設する.
57 #include "floor/wild.h"
58 #include "game-option/birth-options.h"
59 #include "game-option/disturbance-options.h"
60 #include "game-option/game-play-options.h"
61 #include "game-option/input-options.h"
62 #include "game-option/runtime-arguments.h"
63 #include "io-dump/random-art-info-dumper.h"
64 #include "io/record-play-movie.h"
65 #include "io/command-repeater.h"
66 #include "io/files-util.h"
67 #include "io/input-key-requester.h" //!< @todo 相互依存している、後で何とかする.
68 #include "io/write-diary.h"
69 #include "knowledge/knowledge-autopick.h"
70 #include "knowledge/knowledge-quests.h"
71 #include "main/sound-definitions-table.h"
72 #include "main/sound-of-music.h"
73 #include "mind/mind-blue-mage.h"
74 #include "mind/mind-elementalist.h"
75 #include "mind/mind-magic-eater.h"
76 #include "mind/mind-sniper.h"
77 #include "mind/snipe-types.h"
78 #include "player-status/player-energy.h"
79 #include "player/attack-defense-types.h"
80 #include "player/digestion-processor.h"
81 #include "player/player-class.h"
82 #include "player/player-status.h"
83 #include "player/special-defense-types.h"
84 #include "status/action-setter.h"
85 #include "store/home.h"
86 #include "store/cmd-store.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(NULL);
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(NULL);
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  * @return なし
160  */
161 void process_command(player_type *creature_ptr)
162 {
163     COMMAND_CODE old_now_message = now_message;
164     repeat_check();
165     now_message = 0;
166     if ((creature_ptr->pclass == CLASS_SNIPER) && (creature_ptr->concent))
167         creature_ptr->reset_concent = TRUE;
168
169     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
170     switch (command_cmd) {
171     case ESCAPE:
172     case ' ':
173     case '\r':
174     case '\n': {
175         /* Ignore */
176         break;
177     }
178     case KTRL('W'): {
179         if (current_world_ptr->wizard) {
180             current_world_ptr->wizard = FALSE;
181             msg_print(_("ウィザードモード解除。", "Wizard mode off."));
182         } else if (enter_wizard_mode(creature_ptr)) {
183             current_world_ptr->wizard = TRUE;
184             msg_print(_("ウィザードモード突入。", "Wizard mode on."));
185         }
186
187         creature_ptr->update |= (PU_MONSTERS);
188         creature_ptr->redraw |= (PR_TITLE);
189         break;
190     }
191     case KTRL('A'): {
192         if (enter_debug_mode(creature_ptr)) {
193             do_cmd_debug(creature_ptr);
194         }
195
196         break;
197     }
198     case 'w': {
199         if (!creature_ptr->wild_mode)
200             do_cmd_wield(creature_ptr);
201
202         break;
203     }
204     case 't': {
205         if (!creature_ptr->wild_mode)
206             do_cmd_takeoff(creature_ptr);
207
208         break;
209     }
210     case 'd': {
211         if (!creature_ptr->wild_mode)
212             do_cmd_drop(creature_ptr);
213
214         break;
215     }
216     case 'k': {
217         do_cmd_destroy(creature_ptr);
218         break;
219     }
220     case 'e': {
221         do_cmd_equip(creature_ptr);
222         break;
223     }
224     case 'i': {
225         do_cmd_inven(creature_ptr);
226         break;
227     }
228     case 'I': {
229         do_cmd_observe(creature_ptr);
230         break;
231     }
232
233     case KTRL('I'): {
234         toggle_inventory_equipment(creature_ptr);
235         break;
236     }
237     case '+': {
238         if (!creature_ptr->wild_mode)
239             do_cmd_alter(creature_ptr);
240
241         break;
242     }
243     case 'T': {
244         if (!creature_ptr->wild_mode)
245             do_cmd_tunnel(creature_ptr);
246
247         break;
248     }
249     case ';': {
250         do_cmd_walk(creature_ptr, FALSE);
251         break;
252     }
253     case '-': {
254         do_cmd_walk(creature_ptr, TRUE);
255         break;
256     }
257     case '.': {
258         if (!creature_ptr->wild_mode)
259             do_cmd_run(creature_ptr);
260
261         break;
262     }
263     case ',': {
264         do_cmd_stay(creature_ptr, always_pickup);
265         break;
266     }
267     case 'g': {
268         do_cmd_stay(creature_ptr, !always_pickup);
269         break;
270     }
271     case 'R': {
272         do_cmd_rest(creature_ptr);
273         break;
274     }
275     case 's': {
276         do_cmd_search(creature_ptr);
277         break;
278     }
279     case 'S': {
280         if (creature_ptr->action == ACTION_SEARCH)
281             set_action(creature_ptr, ACTION_NONE);
282         else
283             set_action(creature_ptr, ACTION_SEARCH);
284
285         break;
286     }
287     case SPECIAL_KEY_STORE: {
288         do_cmd_store(creature_ptr);
289         break;
290     }
291     case SPECIAL_KEY_BUILDING: {
292         do_cmd_building(creature_ptr);
293         break;
294     }
295     case SPECIAL_KEY_QUEST: {
296         do_cmd_quest(creature_ptr);
297         break;
298     }
299     case '<': {
300         if (!creature_ptr->wild_mode && !floor_ptr->dun_level && !floor_ptr->inside_arena && !floor_ptr->inside_quest) {
301             if (vanilla_town)
302                 break;
303
304             if (creature_ptr->ambush_flag) {
305                 msg_print(_("襲撃から逃げるにはマップの端まで移動しなければならない。", "To flee the ambush you have to reach the edge of the map."));
306                 break;
307             }
308
309             if (creature_ptr->food < PY_FOOD_WEAK) {
310                 msg_print(_("その前に食事をとらないと。", "You must eat something here."));
311                 break;
312             }
313
314             change_wild_mode(creature_ptr, FALSE);
315         } else
316             do_cmd_go_up(creature_ptr);
317
318         break;
319     }
320     case '>': {
321         if (creature_ptr->wild_mode)
322             change_wild_mode(creature_ptr, FALSE);
323         else
324             do_cmd_go_down(creature_ptr);
325
326         break;
327     }
328     case 'o': {
329         do_cmd_open(creature_ptr);
330         break;
331     }
332     case 'c': {
333         do_cmd_close(creature_ptr);
334         break;
335     }
336     case 'j': {
337         do_cmd_spike(creature_ptr);
338         break;
339     }
340     case 'B': {
341         do_cmd_bash(creature_ptr);
342         break;
343     }
344     case 'D': {
345         do_cmd_disarm(creature_ptr);
346         break;
347     }
348     case 'G': {
349         if (creature_ptr->pclass == CLASS_SORCERER || creature_ptr->pclass == CLASS_RED_MAGE || creature_ptr->pclass == CLASS_ELEMENTALIST)
350             msg_print(_("呪文を学習する必要はない!", "You don't have to learn spells!"));
351         else if (creature_ptr->pclass == CLASS_SAMURAI)
352             do_cmd_gain_hissatsu(creature_ptr);
353         else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
354             import_magic_device(creature_ptr);
355         else
356             do_cmd_study(creature_ptr);
357
358         break;
359     }
360     case 'b': {
361         if ((creature_ptr->pclass == CLASS_MINDCRAFTER) || (creature_ptr->pclass == CLASS_BERSERKER) || (creature_ptr->pclass == CLASS_NINJA)
362             || (creature_ptr->pclass == CLASS_MIRROR_MASTER))
363             do_cmd_mind_browse(creature_ptr);
364         else if (creature_ptr->pclass == CLASS_ELEMENTALIST)
365             do_cmd_element_browse(creature_ptr);
366         else if (creature_ptr->pclass == CLASS_SMITH)
367             do_cmd_kaji(creature_ptr, TRUE);
368         else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
369             do_cmd_magic_eater(creature_ptr, TRUE, FALSE);
370         else if (creature_ptr->pclass == CLASS_SNIPER)
371             do_cmd_snipe_browse(creature_ptr);
372         else
373             do_cmd_browse(creature_ptr);
374
375         break;
376     }
377     case 'm': {
378         if (creature_ptr->wild_mode) {
379             break;
380         }
381
382         if ((creature_ptr->pclass == CLASS_WARRIOR) || (creature_ptr->pclass == CLASS_ARCHER) || (creature_ptr->pclass == CLASS_CAVALRY)) {
383             msg_print(_("呪文を唱えられない!", "You cannot cast spells!"));
384             break;
385         }
386         
387         if (floor_ptr->dun_level && (d_info[creature_ptr->dungeon_idx].flags1 & DF1_NO_MAGIC) && (creature_ptr->pclass != CLASS_BERSERKER)
388             && (creature_ptr->pclass != CLASS_SMITH)) {
389             msg_print(_("ダンジョンが魔法を吸収した!", "The dungeon absorbs all attempted magic!"));
390             msg_print(NULL);
391             break;
392         }
393         
394         if (creature_ptr->anti_magic && (creature_ptr->pclass != CLASS_BERSERKER) && (creature_ptr->pclass != CLASS_SMITH)) {
395             concptr which_power = _("魔法", "magic");
396             switch (creature_ptr->pclass) {
397             case CLASS_MINDCRAFTER:
398                 which_power = _("超能力", "psionic powers");
399                 break;
400             case CLASS_IMITATOR:
401                 which_power = _("ものまね", "imitation");
402                 break;
403             case CLASS_SAMURAI:
404                 which_power = _("必殺剣", "hissatsu");
405                 break;
406             case CLASS_MIRROR_MASTER:
407                 which_power = _("鏡魔法", "mirror magic");
408                 break;
409             case CLASS_NINJA:
410                 which_power = _("忍術", "ninjutsu");
411                 break;
412             case CLASS_ELEMENTALIST:
413                 which_power = _("元素魔法", "magic");
414                 break;
415             default:
416                 if (mp_ptr->spell_book == TV_LIFE_BOOK)
417                     which_power = _("祈り", "prayer");
418                 break;
419             }
420
421             msg_format(_("反魔法バリアが%sを邪魔した!", "An anti-magic shell disrupts your %s!"), which_power);
422             PlayerEnergy(creature_ptr).reset_player_turn();
423             break;
424         }
425         
426         if (is_shero(creature_ptr) && (creature_ptr->pclass != CLASS_BERSERKER)) {
427             msg_format(_("狂戦士化していて頭が回らない!", "You cannot think directly!"));
428             PlayerEnergy(creature_ptr).reset_player_turn();
429             break;
430         }
431
432         if ((creature_ptr->pclass == CLASS_MINDCRAFTER) || (creature_ptr->pclass == CLASS_BERSERKER) || (creature_ptr->pclass == CLASS_NINJA)
433             || (creature_ptr->pclass == CLASS_MIRROR_MASTER))
434             do_cmd_mind(creature_ptr);
435         else if (creature_ptr->pclass == CLASS_ELEMENTALIST)
436             do_cmd_element(creature_ptr);
437         else if (creature_ptr->pclass == CLASS_IMITATOR)
438             do_cmd_mane(creature_ptr, FALSE);
439         else if (creature_ptr->pclass == CLASS_MAGIC_EATER)
440             do_cmd_magic_eater(creature_ptr, FALSE, FALSE);
441         else if (creature_ptr->pclass == CLASS_SAMURAI)
442             do_cmd_hissatsu(creature_ptr);
443         else if (creature_ptr->pclass == CLASS_BLUE_MAGE)
444             do_cmd_cast_learned(creature_ptr);
445         else if (creature_ptr->pclass == CLASS_SMITH)
446             do_cmd_kaji(creature_ptr, FALSE);
447         else if (creature_ptr->pclass == CLASS_SNIPER)
448             do_cmd_snipe(creature_ptr);
449         else
450             (void)do_cmd_cast(creature_ptr);
451
452         break;
453     }
454     case 'p': {
455         do_cmd_pet(creature_ptr);
456         break;
457     }
458     case '{': {
459         do_cmd_inscribe(creature_ptr);
460         break;
461     }
462     case '}': {
463         do_cmd_uninscribe(creature_ptr);
464         break;
465     }
466     case 'A': {
467         do_cmd_activate(creature_ptr);
468         break;
469     }
470     case 'E': {
471         do_cmd_eat_food(creature_ptr);
472         break;
473     }
474     case 'F': {
475         do_cmd_refill(creature_ptr);
476         break;
477     }
478     case 'f': {
479         do_cmd_fire(creature_ptr, SP_NONE);
480         break;
481     }
482     case 'v': {
483         do_cmd_throw(creature_ptr, 1, FALSE, -1);
484         break;
485     }
486     case 'a': {
487         do_cmd_aim_wand(creature_ptr);
488         break;
489     }
490     case 'z': {
491         if (use_command && rogue_like_commands) {
492             do_cmd_use(creature_ptr);
493         } else {
494             do_cmd_zap_rod(creature_ptr);
495         }
496
497         break;
498     }
499     case 'q': {
500         do_cmd_quaff_potion(creature_ptr);
501         break;
502     }
503     case 'r': {
504         do_cmd_read_scroll(creature_ptr);
505         break;
506     }
507     case 'u': {
508         if (use_command && !rogue_like_commands)
509             do_cmd_use(creature_ptr);
510         else
511             do_cmd_use_staff(creature_ptr);
512
513         break;
514     }
515     case 'U': {
516         do_cmd_racial_power(creature_ptr);
517         break;
518     }
519     case 'M': {
520         do_cmd_view_map(creature_ptr);
521         break;
522     }
523     case 'L': {
524         do_cmd_locate(creature_ptr);
525         break;
526     }
527     case 'l': {
528         do_cmd_look(creature_ptr);
529         break;
530     }
531     case '*': {
532         do_cmd_target(creature_ptr);
533         break;
534     }
535     case '?': {
536         do_cmd_help(creature_ptr);
537         break;
538     }
539     case '/': {
540         do_cmd_query_symbol(creature_ptr);
541         break;
542     }
543     case 'C': {
544         do_cmd_player_status(creature_ptr);
545         break;
546     }
547     case '!': {
548         (void)term_user(0);
549         break;
550     }
551     case '"': {
552         do_cmd_pref(creature_ptr);
553         break;
554     }
555     case '$': {
556         do_cmd_reload_autopick(creature_ptr);
557         break;
558     }
559     case '_': {
560         do_cmd_edit_autopick(creature_ptr);
561         break;
562     }
563     case '@': {
564         do_cmd_macros(creature_ptr);
565         break;
566     }
567     case '%': {
568         do_cmd_visuals(creature_ptr);
569         do_cmd_redraw(creature_ptr);
570         break;
571     }
572     case '&': {
573         do_cmd_colors(creature_ptr);
574         do_cmd_redraw(creature_ptr);
575         break;
576     }
577     case '=': {
578         do_cmd_options(creature_ptr);
579         (void)combine_and_reorder_home(creature_ptr, STORE_HOME);
580         do_cmd_redraw(creature_ptr);
581         break;
582     }
583     case ':': {
584         do_cmd_note();
585         break;
586     }
587     case 'V': {
588         do_cmd_version();
589         break;
590     }
591     case KTRL('F'): {
592         do_cmd_feeling(creature_ptr);
593         break;
594     }
595     case KTRL('O'): {
596         do_cmd_message_one();
597         break;
598     }
599     case KTRL('P'): {
600         do_cmd_messages(old_now_message);
601         break;
602     }
603     case KTRL('Q'): {
604         do_cmd_checkquest(creature_ptr);
605         break;
606     }
607     case KTRL('R'): {
608         now_message = old_now_message;
609         do_cmd_redraw(creature_ptr);
610         break;
611     }
612     case KTRL('S'): {
613         do_cmd_save_game(creature_ptr, FALSE);
614         break;
615     }
616     case KTRL('T'): {
617         do_cmd_time(creature_ptr);
618         break;
619     }
620     case KTRL('X'):
621     case SPECIAL_KEY_QUIT: {
622         do_cmd_save_and_exit(creature_ptr);
623         break;
624     }
625     case 'Q': {
626         do_cmd_suicide(creature_ptr);
627         break;
628     }
629     case '|': {
630         do_cmd_diary(creature_ptr);
631         break;
632     }
633     case '~': {
634         do_cmd_knowledge(creature_ptr);
635         break;
636     }
637     case '(': {
638         do_cmd_load_screen();
639         break;
640     }
641     case ')': {
642         do_cmd_save_screen(creature_ptr);
643         break;
644     }
645     case ']': {
646         prepare_movie_hooks(creature_ptr);
647         break;
648     }
649     case KTRL('V'): {
650         spoil_random_artifact(creature_ptr, "randifact.txt");
651         break;
652     }
653     case '`': {
654         if (!creature_ptr->wild_mode)
655             do_cmd_travel(creature_ptr);
656         if (creature_ptr->special_defense & KATA_MUSOU) {
657             set_action(creature_ptr, ACTION_NONE);
658         }
659
660         break;
661     }
662     default: {
663         if (flush_failure)
664             flush();
665         if (one_in_(2)) {
666             char error_m[1024];
667             sound(SOUND_ILLEGAL);
668             if (!get_rnd_line(_("error_j.txt", "error.txt"), 0, error_m))
669                 msg_print(error_m);
670         } else {
671             prt(_(" '?' でヘルプが表示されます。", "Type '?' for help."), 0, 0);
672         }
673
674         break;
675     }
676     }
677
678     if (!creature_ptr->energy_use && !now_message)
679         now_message = old_now_message;
680 }