OSDN Git Service

[Refactor] #3409 exe_cmd_debug() におけるswitch/case 文の調整
[hengbandforosx/hengbandosx.git] / src / wizard / cmd-wizard.cpp
1 /*!
2  * @brief デバッグコマンドの分岐実装
3  * @date 2020/08/01
4  * @author Hourier
5  * @details 通常のコマンドではないのでcmd-xxx/ ではなくwizard/ 以下に置く
6  */
7
8 #include "wizard/cmd-wizard.h"
9 #include "birth/inventory-initializer.h"
10 #include "cmd-io/cmd-help.h"
11 #include "core/asking-player.h"
12 #include "inventory/inventory-object.h"
13 #include "inventory/inventory-slot-types.h"
14 #include "io/input-key-requester.h"
15 #include "mutation/mutation-investor-remover.h"
16 #include "player-base/player-class.h"
17 #include "player/patron.h"
18 #include "spell-kind/spells-detection.h"
19 #include "spell-kind/spells-floor.h"
20 #include "spell-kind/spells-perception.h"
21 #include "spell-kind/spells-sight.h"
22 #include "spell-kind/spells-teleport.h"
23 #include "spell/spells-status.h"
24 #include "status/experience.h"
25 #include "system/floor-type-definition.h"
26 #include "system/grid-type-definition.h"
27 #include "system/item-entity.h"
28 #include "system/player-type-definition.h"
29 #include "term/screen-processor.h"
30 #include "util/int-char-converter.h"
31 #include "view/display-messages.h"
32 #include "wizard/wizard-game-modifier.h"
33 #include "wizard/wizard-item-modifier.h"
34 #include "wizard/wizard-player-modifier.h"
35 #include "wizard/wizard-special-process.h"
36 #include "wizard/wizard-spells.h"
37 #include "wizard/wizard-spoiler.h"
38 #include <sstream>
39 #include <string>
40 #include <tuple>
41 #include <vector>
42
43 /*!
44  * @brief デバグコマンド一覧表
45  * @details
46  * 空き: A,B,E,I,J,k,K,L,M,q,Q,R,T,U,V,W,y,Y
47  */
48 constexpr std::array debug_menu_table = {
49     std::make_tuple('a', _("全状態回復", "Restore all status")),
50     std::make_tuple('b', _("現在のターゲットを引き寄せる", "Teleport target back")),
51     std::make_tuple('c', _("オブジェクト生成", "Create object")),
52     std::make_tuple('C', _("固定アーティファクト生成", "Create fixed artifact")),
53     std::make_tuple('d', _("全感知", "Detection all")),
54     std::make_tuple('D', _("次元の扉", "Dimension door")),
55     std::make_tuple('e', _("能力値変更", "Modify player status")),
56     std::make_tuple('E', _("青魔法を全取得/エッセンスを全取得", "Learn all blue magics / Obtain all essences")),
57     std::make_tuple('f', _("*鑑定*", "*Idenfity*")),
58     std::make_tuple('F', _("地形ID変更", "Modify feature type under player")),
59     std::make_tuple('G', _("ゲーム設定コマンドメニュー", "Modify game configurations")),
60     std::make_tuple('H', _("モンスターの群れ生成", "Summon monsters")),
61     std::make_tuple('i', _("鑑定", "Idenfity")),
62     std::make_tuple('I', _("アイテム設定コマンドメニュー", "Modify item configurations")),
63     std::make_tuple('j', _("指定ダンジョン階にワープ", "Jump to floor depth of target dungeon")),
64     std::make_tuple('k', _("指定ダメージ・半径0の指定属性のボールを自分に放つ", "Fire a zero ball to self")),
65     std::make_tuple('m', _("魔法の地図", "Magic mapping")),
66     std::make_tuple('n', _("指定モンスター生成", "Summon target monster")),
67     std::make_tuple('N', _("指定モンスターをペットとして生成", "Summon target monster as pet")),
68     std::make_tuple('o', _("オブジェクトの能力変更", "Modift object abilities")),
69     std::make_tuple('O', _("オプション設定をダンプ", "Dump current options")),
70     std::make_tuple('p', _("ショート・テレポート", "Phase door")),
71     std::make_tuple('P', _("プレイヤー設定変更メニュー", "Modify player configurations")),
72     std::make_tuple('r', _("カオスパトロンの報酬", "Get reward of chaos patron")),
73     std::make_tuple('s', _("フロア相当のモンスター召喚", "Summon monster which be in target depth")),
74     std::make_tuple('t', _("テレポート", "Teleport self")),
75     std::make_tuple('u', _("啓蒙(忍者以外)", "Wiz-lite all floor except Ninja")),
76     std::make_tuple('w', _("啓蒙(忍者配慮)", "Wiz-lite all floor")),
77     std::make_tuple('x', _("経験値を得る(指定可)", "Get experience")),
78     std::make_tuple('X', _("所持品を初期状態に戻す", "Return inventory to initial")),
79     std::make_tuple('y', _("ダメージ100万・半径0の射撃のボールを放つ", "Cast missile ball had power a million")),
80     std::make_tuple('Y', _("指定ダメージ・半径0の指定属性のボールを放つ", "Cast zero ball had power a thousand")),
81     std::make_tuple('z', _("近隣のモンスター消去", "Terminate near monsters")),
82     std::make_tuple('Z', _("フロアの全モンスター消去", "Terminate all monsters in floor")),
83     std::make_tuple('@', _("特殊スペルの発動", "Activate specified spells")),
84     std::make_tuple('"', _("スポイラーのダンプ", "Dump spoiler")),
85     std::make_tuple('?', _("ヘルプ表示", "Help")),
86 };
87
88 /*!
89  * @brief デバグコマンドの一覧を表示する
90  * @param page ページ番号
91  * @param max_page ページ数
92  * @param page_size 1ページ行数
93  * @param max_line コマンド数
94  */
95 void display_debug_menu(int page, int max_page, int page_size, int max_line)
96 {
97     for (int y = 1; y < page_size + 3; y++) {
98         term_erase(14, y, 64);
99     }
100
101     int r = 1;
102     int c = 15;
103     for (int i = 0; i < page_size; i++) {
104         int pos = page * page_size + i;
105         if (pos >= max_line) {
106             break;
107         }
108
109         std::stringstream ss;
110         const auto &[symbol, desc] = debug_menu_table[pos];
111         ss << symbol << ") " << desc;
112         put_str(ss.str(), r++, c);
113     }
114     if (max_page > 1) {
115         put_str("-- more --", r++, c);
116     }
117 }
118
119 /*!
120  * @brief デバッグコマンド選択処理への分岐
121  * @param player_ptr プレイヤーへの参照ポインタ
122  * @param cmd コマンドキー
123  * @return コマンド終了ならTRUE、ページ送りならFALSE
124  */
125 bool exe_cmd_debug(PlayerType *player_ptr, char cmd)
126 {
127     switch (cmd) {
128     case ' ':
129     case '<':
130     case '>':
131     case KTRL('a'):
132         return false;
133     case ESCAPE:
134     case '\n':
135     case '\r':
136         return true;
137     case 'a':
138         wiz_cure_all(player_ptr);
139         return true;
140     case 'b':
141         wiz_teleport_back(player_ptr);
142         return true;
143     case 'c':
144         wiz_create_item(player_ptr);
145         return true;
146     case 'C':
147         wiz_create_named_art(player_ptr);
148         return true;
149     case 'd':
150         detect_all(player_ptr, DETECT_RAD_ALL * 3);
151         return true;
152     case 'D':
153         wiz_dimension_door(player_ptr);
154         return true;
155     case 'e':
156         wiz_change_status(player_ptr);
157         return true;
158     case 'E':
159         switch (player_ptr->pclass) {
160         case PlayerClassType::BLUE_MAGE:
161             wiz_learn_blue_magic_all(player_ptr);
162             break;
163         case PlayerClassType::SMITH:
164             wiz_fillup_all_smith_essences(player_ptr);
165             break;
166         default:
167             break;
168         }
169
170         return true;
171     case 'f':
172         identify_fully(player_ptr, false);
173         return true;
174     case 'F':
175         wiz_create_feature(player_ptr);
176         return true;
177     case 'G':
178         wizard_game_modifier(player_ptr);
179         return true;
180     case 'H':
181         wiz_summon_horde(player_ptr);
182         return true;
183     case 'i':
184         (void)ident_spell(player_ptr, false);
185         return true;
186     case 'I':
187         wizard_item_modifier(player_ptr);
188         return true;
189     case 'j':
190         wiz_jump_to_dungeon(player_ptr);
191         return true;
192     case 'k':
193         wiz_kill_target(player_ptr, 0, (AttributeType)command_arg, true);
194         return true;
195     case 'm':
196         map_area(player_ptr, DETECT_RAD_ALL * 3);
197         return true;
198     case 'n':
199         wiz_summon_specific_enemy(player_ptr, i2enum<MonsterRaceId>(command_arg));
200         return true;
201     case 'N':
202         wiz_summon_pet(player_ptr, i2enum<MonsterRaceId>(command_arg));
203         return true;
204     case 'o':
205         wiz_modify_item(player_ptr);
206         return true;
207     case 'O':
208         wiz_dump_options();
209         return true;
210     case 'p':
211         teleport_player(player_ptr, 10, TELEPORT_SPONTANEOUS);
212         return true;
213     case 'P':
214         wizard_player_modifier(player_ptr);
215         return true;
216     case 'r':
217         patron_list[player_ptr->chaos_patron].gain_level_reward(player_ptr, command_arg);
218         return true;
219     case 's':
220         if (command_arg <= 0) {
221             command_arg = 1;
222         }
223
224         wiz_summon_random_enemy(player_ptr, command_arg);
225         return true;
226     case 't':
227         teleport_player(player_ptr, 100, TELEPORT_SPONTANEOUS);
228         return true;
229     case 'u':
230         for (int y = 0; y < player_ptr->current_floor_ptr->height; y++) {
231             for (int x = 0; x < player_ptr->current_floor_ptr->width; x++) {
232                 player_ptr->current_floor_ptr->grid_array[y][x].info |= CAVE_GLOW | CAVE_MARK;
233             }
234         }
235
236         wiz_lite(player_ptr, false);
237         return true;
238     case 'w':
239         wiz_lite(player_ptr, PlayerClass(player_ptr).equals(PlayerClassType::NINJA));
240         return true;
241     case 'x':
242         gain_exp(player_ptr, command_arg ? command_arg : (player_ptr->exp + 1));
243         return true;
244     case 'X':
245         for (INVENTORY_IDX i = INVEN_TOTAL - 1; i >= 0; i--) {
246             if (player_ptr->inventory_list[i].is_valid()) {
247                 drop_from_inventory(player_ptr, i, 999);
248             }
249         }
250
251         player_outfit(player_ptr);
252         return true;
253     case 'y':
254         wiz_kill_target(player_ptr);
255         return true;
256     case 'Y':
257         wiz_kill_target(player_ptr, 0, (AttributeType)command_arg);
258         return true;
259     case 'z':
260         wiz_zap_surrounding_monsters(player_ptr);
261         return true;
262     case 'Z':
263         wiz_zap_floor_monsters(player_ptr);
264         return true;
265     case '_':
266         probing(player_ptr);
267         return true;
268     case '@':
269         wiz_debug_spell(player_ptr);
270         return true;
271     case '"':
272         exe_output_spoilers();
273         return true;
274     case '?':
275         do_cmd_help(player_ptr);
276         return true;
277     default:
278         msg_print("That is not a valid debug command.");
279         return true;
280     }
281 }
282
283 /*!
284  * @brief デバッグコマンドを選択する処理のメインルーチン /
285  * Ask for and parse a "debug command"
286  * The "command_arg" may have been set.
287  * @param player_ptr プレイヤーへの参照ポインタ
288  * @details
289  * 番号を指定するには、それをN及びデバッグコマンドをXとしてとして「0N^aX」とする
290  */
291 void do_cmd_debug(PlayerType *player_ptr)
292 {
293     TERM_LEN hgt, wid;
294     term_get_size(&wid, &hgt);
295
296     size_t max_line = debug_menu_table.size();
297     int page_size = hgt - 5;
298     int max_page = max_line / page_size + 1;
299     int page = 0;
300     char cmd;
301
302     while (true) {
303         screen_save();
304         display_debug_menu(page, max_page, page_size, max_line);
305         get_com("Debug Command: ", &cmd, false);
306         screen_load();
307
308         if (exe_cmd_debug(player_ptr, cmd)) {
309             break;
310         }
311
312         page = (page + 1) % max_page;
313     }
314 }