OSDN Git Service

[Refactor] struct player_type を class PlayerType に置換。
[hengbandforosx/hengbandosx.git] / src / inventory / floor-item-getter.cpp
1 /*!
2  * @brief オブジェクト選択処理
3  * @date 2020/07/02
4  * @author Hourier
5  */
6
7 #include "inventory/floor-item-getter.h"
8 #include "core/stuff-handler.h"
9 #include "core/window-redrawer.h"
10 #include "floor/floor-object.h"
11 #include "floor/object-scanner.h"
12 #include "game-option/input-options.h"
13 #include "game-option/option-flags.h"
14 #include "game-option/text-display-options.h"
15 #include "inventory/inventory-slot-types.h"
16 #include "inventory/inventory-util.h"
17 #include "inventory/item-selection-util.h"
18 #include "io/command-repeater.h"
19 #include "io/input-key-acceptor.h"
20 #include "io/input-key-requester.h"
21 #include "main/sound-of-music.h"
22 #include "object/item-tester-hooker.h"
23 #include "object/item-use-flags.h"
24 #include "object/object-info.h"
25 #include "player/player-status-flags.h"
26 #include "system/floor-type-definition.h"
27 #include "system/grid-type-definition.h"
28 #include "system/object-type-definition.h"
29 #include "system/player-type-definition.h"
30 #include "term/gameterm.h"
31 #include "term/screen-processor.h"
32 #include "util/int-char-converter.h"
33 #include "view/display-inventory.h"
34 #include "view/display-messages.h"
35 #include "window/display-sub-windows.h"
36
37 /*!
38  * @brief 床上アイテムへにタグ付けがされているかの調査処理 (のはず)
39  * @param player_ptr プレイヤーへの参照ポインタ
40  * @param fis_ptr 床上アイテムへの参照ポインタ
41  * @param prev_tag 前回選択したアイテムのタグ (のはず)
42  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
43  * @todo 適切な関数名をどうしても付けられなかったので暫定でauxとした
44  */
45 static bool check_floor_item_tag_aux(PlayerType *player_ptr, fis_type *fis_ptr, char *prev_tag, const ItemTester& item_tester)
46 {
47     if (!fis_ptr->floor || (*fis_ptr->cp >= 0))
48         return false;
49
50     if (*prev_tag && command_cmd) {
51         fis_ptr->floor_num
52             = scan_floor_items(player_ptr, fis_ptr->floor_list, player_ptr->y, player_ptr->x, SCAN_FLOOR_ITEM_TESTER | SCAN_FLOOR_ONLY_MARKED, item_tester);
53         if (get_tag_floor(player_ptr->current_floor_ptr, &fis_ptr->k, *prev_tag, fis_ptr->floor_list, fis_ptr->floor_num)) {
54             *fis_ptr->cp = 0 - fis_ptr->floor_list[fis_ptr->k];
55             command_cmd = 0;
56             return true;
57         }
58
59         *prev_tag = '\0';
60         return false;
61     }
62
63     if (!item_tester.okay(&player_ptr->current_floor_ptr->o_list[0 - (*fis_ptr->cp)]) && ((fis_ptr->mode & USE_FULL) == 0))
64         return false;
65
66     command_cmd = 0;
67     return true;
68 }
69
70 /*!
71  * @brief インベントリのアイテムにタグ付けを試みる
72  * @param player_ptr プレイヤーへの参照ポインタ
73  * @param fis_ptr 床上アイテムへの参照ポインタ
74  * @param prev_tag 前回選択したアイテムのタグ (のはず)
75  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
76  */
77 static bool get_floor_item_tag_inventory(PlayerType *player_ptr, fis_type *fis_ptr, char *prev_tag, const ItemTester& item_tester)
78 {
79     bool flag = false;
80     item_use_flag use_flag = (*fis_ptr->cp >= INVEN_MAIN_HAND) ? USE_EQUIP : USE_INVEN;
81
82     flag |= !get_tag(player_ptr, &fis_ptr->k, *prev_tag, use_flag, item_tester);
83     flag |= !get_item_okay(player_ptr, fis_ptr->k, item_tester);
84
85     if (fis_ptr->k < INVEN_MAIN_HAND)
86         flag |= !fis_ptr->inven;
87     else
88         flag |= !fis_ptr->equip;
89
90     if (flag) {
91         *prev_tag = '\0';
92         return false;
93     }
94
95     *fis_ptr->cp = fis_ptr->k;
96     command_cmd = 0;
97     return true;
98 }
99
100 /*!
101  * @brief インベントリのアイテムにタグ付けがされているかの調査処理 (のはず)
102  * @param player_ptr プレイヤーへの参照ポインタ
103  * @param fis_ptr 床上アイテムへの参照ポインタ
104  * @param prev_tag 前回選択したアイテムのタグ (のはず)
105  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
106  */
107 static bool check_floor_item_tag_inventory(PlayerType *player_ptr, fis_type *fis_ptr, char *prev_tag, const ItemTester& item_tester)
108 {
109     if ((!fis_ptr->inven || (*fis_ptr->cp < 0) || (*fis_ptr->cp >= INVEN_PACK))
110         && (!fis_ptr->equip || (*fis_ptr->cp < INVEN_MAIN_HAND) || (*fis_ptr->cp >= INVEN_TOTAL)))
111         return false;
112
113     if ((*prev_tag != '\0') && command_cmd)
114         return get_floor_item_tag_inventory(player_ptr, fis_ptr, prev_tag, item_tester);
115
116     if (get_item_okay(player_ptr, *fis_ptr->cp, item_tester)) {
117         command_cmd = 0;
118         return true;
119     }
120
121     return false;
122 }
123
124 /*!
125  * @brief 床上アイテムにタグ付けがされているかの調査処理 (のはず)
126  * @param player_ptr プレイヤーへの参照ポインタ
127  * @param fis_ptr 床上アイテムへの参照ポインタ
128  * @param prev_tag 前回選択したアイテムのタグ (のはず)
129  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
130  */
131 static bool check_floor_item_tag(PlayerType *player_ptr, fis_type *fis_ptr, char *prev_tag, const ItemTester& item_tester)
132 {
133     if (!repeat_pull(fis_ptr->cp))
134         return false;
135
136     if (fis_ptr->force && (*fis_ptr->cp == INVEN_FORCE)) {
137         command_cmd = 0;
138         return true;
139     }
140
141     if (check_floor_item_tag_aux(player_ptr, fis_ptr, prev_tag, item_tester))
142         return true;
143
144     return check_floor_item_tag_inventory(player_ptr, fis_ptr, prev_tag, item_tester);
145 }
146
147 /*!
148  * @brief インベントリ内のアイテムが妥当かを判定する
149  * @param player_ptr プレイヤーへの参照ポインタ
150  * @param fis_ptr 床上アイテムへの参照ポインタ
151  */
152 static void test_inventory_floor(PlayerType *player_ptr, fis_type *fis_ptr, const ItemTester& item_tester)
153 {
154     if (!fis_ptr->inven) {
155         fis_ptr->i2 = -1;
156         return;
157     }
158
159     if (!use_menu)
160         return;
161
162     for (int i = 0; i < INVEN_PACK; i++)
163         if (item_tester.okay(&player_ptr->inventory_list[i]) || (fis_ptr->mode & USE_FULL))
164             fis_ptr->max_inven++;
165 }
166
167 /*!
168  * @brief 装備品がが妥当かを判定する
169  * @param player_ptr プレイヤーへの参照ポインタ
170  * @param fis_ptr 床上アイテムへの参照ポインタ
171  */
172 static void test_equipment_floor(PlayerType *player_ptr, fis_type *fis_ptr, const ItemTester& item_tester)
173 {
174     if (!fis_ptr->equip) {
175         fis_ptr->e2 = -1;
176         return;
177     }
178
179     if (!use_menu)
180         return;
181
182     for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++)
183         if (player_ptr->select_ring_slot ? is_ring_slot(i)
184                                         : item_tester.okay(&player_ptr->inventory_list[i]) || (fis_ptr->mode & USE_FULL))
185             fis_ptr->max_equip++;
186 }
187
188 /*!
189  * @brief オブジェクト選択の汎用関数(床上アイテム用) /
190  * Let the user select an item, save its "index"
191  * @param cp 選択したオブジェクトのIDを返す。
192  * @param pmt 選択目的のメッセージ
193  * @param str 選択できるオブジェクトがない場合のキャンセルメッセージ
194  * @param mode オプションフラグ
195  * @return プレイヤーによりアイテムが選択されたならTRUEを返す。/
196  */
197 bool get_item_floor(PlayerType *player_ptr, COMMAND_CODE *cp, concptr pmt, concptr str, BIT_FLAGS mode, const ItemTester& item_tester)
198 {
199     fis_type tmp_fis;
200     fis_type *fis_ptr = initialize_fis_type(&tmp_fis, cp, mode);
201     static char prev_tag = '\0';
202     if (check_floor_item_tag(player_ptr, fis_ptr, &prev_tag, item_tester))
203         return true;
204
205     msg_print(nullptr);
206     handle_stuff(player_ptr);
207     test_inventory_floor(player_ptr, fis_ptr, item_tester);
208     fis_ptr->done = false;
209     fis_ptr->item = false;
210     fis_ptr->i1 = 0;
211     fis_ptr->i2 = INVEN_PACK - 1;
212     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(player_ptr, fis_ptr->i1, item_tester)))
213         fis_ptr->i1++;
214
215     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(player_ptr, fis_ptr->i2, item_tester)))
216         fis_ptr->i2--;
217
218     fis_ptr->e1 = INVEN_MAIN_HAND;
219     fis_ptr->e2 = INVEN_TOTAL - 1;
220     test_equipment_floor(player_ptr, fis_ptr, item_tester);
221     if (has_two_handed_weapons(player_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT))
222         fis_ptr->max_equip++;
223
224     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(player_ptr, fis_ptr->e1, item_tester)))
225         fis_ptr->e1++;
226
227     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(player_ptr, fis_ptr->e2, item_tester)))
228         fis_ptr->e2--;
229
230     if (fis_ptr->equip && has_two_handed_weapons(player_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT)) {
231         if (can_attack_with_main_hand(player_ptr)) {
232             if (fis_ptr->e2 < INVEN_SUB_HAND)
233                 fis_ptr->e2 = INVEN_SUB_HAND;
234         } else if (can_attack_with_sub_hand(player_ptr))
235             fis_ptr->e1 = INVEN_MAIN_HAND;
236     }
237
238     fis_ptr->floor_num = 0;
239     if (fis_ptr->floor)
240         fis_ptr->floor_num
241             = scan_floor_items(player_ptr, fis_ptr->floor_list, player_ptr->y, player_ptr->x, SCAN_FLOOR_ITEM_TESTER | SCAN_FLOOR_ONLY_MARKED, item_tester);
242
243     if ((mode & USE_INVEN) && (fis_ptr->i1 <= fis_ptr->i2))
244         fis_ptr->allow_inven = true;
245
246     if ((mode & USE_EQUIP) && (fis_ptr->e1 <= fis_ptr->e2))
247         fis_ptr->allow_equip = true;
248
249     if ((mode & USE_FLOOR) && (fis_ptr->floor_num))
250         fis_ptr->allow_floor = true;
251
252     if (!fis_ptr->allow_inven && !fis_ptr->allow_equip && !fis_ptr->allow_floor) {
253         command_see = false;
254         fis_ptr->oops = true;
255         fis_ptr->done = true;
256
257         if (fis_ptr->force) {
258             *cp = INVEN_FORCE;
259             fis_ptr->item = true;
260         }
261     } else {
262         if (command_see && (command_wrk == USE_EQUIP) && fis_ptr->allow_equip)
263             command_wrk = USE_EQUIP;
264         else if (fis_ptr->allow_inven)
265             command_wrk = USE_INVEN;
266         else if (fis_ptr->allow_equip)
267             command_wrk = USE_EQUIP;
268         else if (fis_ptr->allow_floor)
269             command_wrk = USE_FLOOR;
270     }
271
272     /* 追加オプション(always_show_list)が設定されている場合は常に一覧を表示する */
273     if (always_show_list || use_menu)
274         command_see = true;
275
276     if (command_see)
277         screen_save();
278
279     while (!fis_ptr->done) {
280         int ni = 0;
281         int ne = 0;
282         for (int i = 0; i < 8; i++) {
283             if (!angband_term[i])
284                 continue;
285
286             if (window_flag[i] & PW_INVEN)
287                 ni++;
288
289             if (window_flag[i] & PW_EQUIP)
290                 ne++;
291         }
292
293         if ((command_wrk == (USE_EQUIP) && ni && !ne) || (command_wrk == (USE_INVEN) && !ni && ne)) {
294             toggle_inventory_equipment(player_ptr);
295             fis_ptr->toggle = !fis_ptr->toggle;
296         }
297
298         player_ptr->window_flags |= (PW_INVEN | PW_EQUIP);
299         handle_stuff(player_ptr);
300         COMMAND_CODE get_item_label = 0;
301         if (command_wrk == USE_INVEN) {
302             fis_ptr->n1 = I2A(fis_ptr->i1);
303             fis_ptr->n2 = I2A(fis_ptr->i2);
304             if (command_see)
305                 get_item_label = show_inventory(player_ptr, fis_ptr->menu_line, fis_ptr->mode, item_tester);
306         } else if (command_wrk == USE_EQUIP) {
307             fis_ptr->n1 = I2A(fis_ptr->e1 - INVEN_MAIN_HAND);
308             fis_ptr->n2 = I2A(fis_ptr->e2 - INVEN_MAIN_HAND);
309             if (command_see)
310                 get_item_label = show_equipment(player_ptr, fis_ptr->menu_line, mode, item_tester);
311         } else if (command_wrk == USE_FLOOR) {
312             int j = fis_ptr->floor_top;
313             fis_ptr->k = std::min(fis_ptr->floor_top + 23, fis_ptr->floor_num) - 1;
314             fis_ptr->n1 = I2A(j - fis_ptr->floor_top); // TODO: 常に'0'になる。どんな意図でこのようなコードになっているのか不明.
315             fis_ptr->n2 = I2A(fis_ptr->k - fis_ptr->floor_top);
316             if (command_see)
317                 get_item_label = show_floor_items(player_ptr, fis_ptr->menu_line, player_ptr->y, player_ptr->x, &fis_ptr->min_width, item_tester);
318         }
319
320         if (command_wrk == USE_INVEN) {
321             sprintf(fis_ptr->out_val, _("持ち物:", "Inven:"));
322             if (!use_menu) {
323                 char tmp_val[80];
324                 sprintf(tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->i1), index_to_label(fis_ptr->i2));
325                 strcat(fis_ptr->out_val, tmp_val);
326             }
327
328             if (!command_see && !use_menu)
329                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
330
331             if (fis_ptr->allow_equip) {
332                 if (!use_menu)
333                     strcat(fis_ptr->out_val, _(" '/' 装備品,", " / for Equip,"));
334                 else if (fis_ptr->allow_floor)
335                     strcat(fis_ptr->out_val, _(" '6' 装備品,", " 6 for Equip,"));
336                 else
337                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
338             }
339
340             if (fis_ptr->allow_floor) {
341                 if (!use_menu)
342                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
343                 else if (fis_ptr->allow_equip)
344                     strcat(fis_ptr->out_val, _(" '4' 床上,", " 4 for floor,"));
345                 else
346                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
347             }
348         } else if (command_wrk == (USE_EQUIP)) {
349             sprintf(fis_ptr->out_val, _("装備品:", "Equip:"));
350             if (!use_menu) {
351                 char tmp_val[80];
352                 sprintf(tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->e1), index_to_label(fis_ptr->e2));
353                 strcat(fis_ptr->out_val, tmp_val);
354             }
355
356             if (!command_see && !use_menu)
357                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
358
359             if (fis_ptr->allow_inven) {
360                 if (!use_menu)
361                     strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
362                 else if (fis_ptr->allow_floor)
363                     strcat(fis_ptr->out_val, _(" '4' 持ち物,", " 4 for Inven,"));
364                 else
365                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
366             }
367
368             if (fis_ptr->allow_floor) {
369                 if (!use_menu)
370                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
371                 else if (fis_ptr->allow_inven)
372                     strcat(fis_ptr->out_val, _(" '6' 床上,", " 6 for floor,"));
373                 else
374                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
375             }
376         } else if (command_wrk == USE_FLOOR) {
377             sprintf(fis_ptr->out_val, _("床上:", "Floor:"));
378             if (!use_menu) {
379                 char tmp_val[80];
380                 sprintf(tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), fis_ptr->n1, fis_ptr->n2);
381                 strcat(fis_ptr->out_val, tmp_val);
382             }
383
384             if (!command_see && !use_menu)
385                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
386
387             if (use_menu) {
388                 if (fis_ptr->allow_inven && fis_ptr->allow_equip) {
389                     strcat(fis_ptr->out_val, _(" '4' 装備品, '6' 持ち物,", " 4 for Equip, 6 for Inven,"));
390                 } else if (fis_ptr->allow_inven) {
391                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
392                 } else if (fis_ptr->allow_equip) {
393                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
394                 }
395             } else if (fis_ptr->allow_inven) {
396                 strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
397             } else if (fis_ptr->allow_equip) {
398                 strcat(fis_ptr->out_val, _(" '/'装備品,", " / for Equip,"));
399             }
400
401             if (command_see && !use_menu) {
402                 strcat(fis_ptr->out_val, _(" Enter 次,", " Enter for scroll down,"));
403             }
404         }
405
406         if (fis_ptr->force)
407             strcat(fis_ptr->out_val, _(" 'w'練気術,", " w for the Force,"));
408
409         strcat(fis_ptr->out_val, " ESC");
410         sprintf(fis_ptr->tmp_val, "(%s) %s", fis_ptr->out_val, pmt);
411         prt(fis_ptr->tmp_val, 0, 0);
412         fis_ptr->which = inkey();
413         if (use_menu) {
414             int max_line = 1;
415             if (command_wrk == USE_INVEN)
416                 max_line = fis_ptr->max_inven;
417             else if (command_wrk == USE_EQUIP)
418                 max_line = fis_ptr->max_equip;
419             else if (command_wrk == USE_FLOOR)
420                 max_line = std::min(23, fis_ptr->floor_num);
421             switch (fis_ptr->which) {
422             case ESCAPE:
423             case 'z':
424             case 'Z':
425             case '0': {
426                 fis_ptr->done = true;
427                 break;
428             }
429             case '8':
430             case 'k':
431             case 'K': {
432                 fis_ptr->menu_line += (max_line - 1);
433                 break;
434             }
435             case '2':
436             case 'j':
437             case 'J': {
438                 fis_ptr->menu_line++;
439                 break;
440             }
441             case '4':
442             case 'h':
443             case 'H': {
444                 if (command_wrk == (USE_INVEN)) {
445                     if (fis_ptr->allow_floor)
446                         command_wrk = USE_FLOOR;
447                     else if (fis_ptr->allow_equip)
448                         command_wrk = USE_EQUIP;
449                     else {
450                         bell();
451                         break;
452                     }
453                 } else if (command_wrk == (USE_EQUIP)) {
454                     if (fis_ptr->allow_inven)
455                         command_wrk = USE_INVEN;
456                     else if (fis_ptr->allow_floor)
457                         command_wrk = USE_FLOOR;
458                     else {
459                         bell();
460                         break;
461                     }
462                 } else if (command_wrk == (USE_FLOOR)) {
463                     if (fis_ptr->allow_equip)
464                         command_wrk = USE_EQUIP;
465                     else if (fis_ptr->allow_inven)
466                         command_wrk = USE_INVEN;
467                     else {
468                         bell();
469                         break;
470                     }
471                 } else {
472                     bell();
473                     break;
474                 }
475
476                 if (command_see) {
477                     screen_load();
478                     screen_save();
479                 }
480
481                 if (command_wrk == USE_INVEN)
482                     max_line = fis_ptr->max_inven;
483                 else if (command_wrk == USE_EQUIP)
484                     max_line = fis_ptr->max_equip;
485                 else if (command_wrk == USE_FLOOR)
486                     max_line = std::min(23, fis_ptr->floor_num);
487
488                 if (fis_ptr->menu_line > max_line)
489                     fis_ptr->menu_line = max_line;
490
491                 break;
492             }
493             case '6':
494             case 'l':
495             case 'L': {
496                 if (command_wrk == (USE_INVEN)) {
497                     if (fis_ptr->allow_equip)
498                         command_wrk = USE_EQUIP;
499                     else if (fis_ptr->allow_floor)
500                         command_wrk = USE_FLOOR;
501                     else {
502                         bell();
503                         break;
504                     }
505                 } else if (command_wrk == (USE_EQUIP)) {
506                     if (fis_ptr->allow_floor)
507                         command_wrk = USE_FLOOR;
508                     else if (fis_ptr->allow_inven)
509                         command_wrk = USE_INVEN;
510                     else {
511                         bell();
512                         break;
513                     }
514                 } else if (command_wrk == (USE_FLOOR)) {
515                     if (fis_ptr->allow_inven)
516                         command_wrk = USE_INVEN;
517                     else if (fis_ptr->allow_equip)
518                         command_wrk = USE_EQUIP;
519                     else {
520                         bell();
521                         break;
522                     }
523                 } else {
524                     bell();
525                     break;
526                 }
527
528                 if (command_see) {
529                     screen_load();
530                     screen_save();
531                 }
532
533                 if (command_wrk == USE_INVEN)
534                     max_line = fis_ptr->max_inven;
535                 else if (command_wrk == USE_EQUIP)
536                     max_line = fis_ptr->max_equip;
537                 else if (command_wrk == USE_FLOOR)
538                     max_line = std::min(23, fis_ptr->floor_num);
539
540                 if (fis_ptr->menu_line > max_line)
541                     fis_ptr->menu_line = max_line;
542
543                 break;
544             }
545             case 'x':
546             case 'X':
547             case '\r':
548             case '\n': {
549                 if (command_wrk == USE_FLOOR)
550                     *cp = -get_item_label;
551                 else {
552                     if (!get_item_okay(player_ptr, get_item_label, item_tester)) {
553                         bell();
554                         break;
555                     }
556
557                     if (!get_item_allow(player_ptr, get_item_label)) {
558                         fis_ptr->done = true;
559                         break;
560                     }
561
562                     *cp = get_item_label;
563                 }
564
565                 fis_ptr->item = true;
566                 fis_ptr->done = true;
567                 break;
568             }
569             case 'w': {
570                 if (fis_ptr->force) {
571                     *cp = INVEN_FORCE;
572                     fis_ptr->item = true;
573                     fis_ptr->done = true;
574                     break;
575                 }
576             }
577             }
578
579             if (fis_ptr->menu_line > max_line)
580                 fis_ptr->menu_line -= max_line;
581
582             continue;
583         }
584
585         switch (fis_ptr->which) {
586         case ESCAPE: {
587             fis_ptr->done = true;
588             break;
589         }
590         case '*':
591         case '?':
592         case ' ': {
593             if (command_see) {
594                 command_see = false;
595                 screen_load();
596             } else {
597                 screen_save();
598                 command_see = true;
599             }
600
601             break;
602         }
603         case '\n':
604         case '\r':
605         case '+': {
606             grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[player_ptr->y][player_ptr->x];
607             if (command_wrk != (USE_FLOOR))
608                 break;
609
610             if (g_ptr->o_idx_list.size() < 2)
611                 break;
612
613             const auto next_o_idx = fis_ptr->floor_list[1];
614             while (g_ptr->o_idx_list.front() != next_o_idx)
615                 g_ptr->o_idx_list.rotate(player_ptr->current_floor_ptr);
616
617             player_ptr->window_flags |= PW_FLOOR_ITEM_LIST;
618             window_stuff(player_ptr);
619
620             fis_ptr->floor_num
621                 = scan_floor_items(player_ptr, fis_ptr->floor_list, player_ptr->y, player_ptr->x, SCAN_FLOOR_ITEM_TESTER | SCAN_FLOOR_ONLY_MARKED, item_tester);
622             if (command_see) {
623                 screen_load();
624                 screen_save();
625             }
626
627             break;
628         }
629         case '/': {
630             if (command_wrk == (USE_INVEN)) {
631                 if (!fis_ptr->allow_equip) {
632                     bell();
633                     break;
634                 }
635                 command_wrk = (USE_EQUIP);
636             } else if (command_wrk == (USE_EQUIP)) {
637                 if (!fis_ptr->allow_inven) {
638                     bell();
639                     break;
640                 }
641                 command_wrk = (USE_INVEN);
642             } else if (command_wrk == (USE_FLOOR)) {
643                 if (fis_ptr->allow_inven) {
644                     command_wrk = (USE_INVEN);
645                 } else if (fis_ptr->allow_equip) {
646                     command_wrk = (USE_EQUIP);
647                 } else {
648                     bell();
649                     break;
650                 }
651             }
652
653             if (command_see) {
654                 screen_load();
655                 screen_save();
656             }
657
658             break;
659         }
660         case '-': {
661             if (!fis_ptr->allow_floor) {
662                 bell();
663                 break;
664             }
665
666             if (fis_ptr->floor_num == 1) {
667                 if ((command_wrk == (USE_FLOOR)) || (!carry_query_flag)) {
668                     fis_ptr->k = 0 - fis_ptr->floor_list[0];
669                     if (!get_item_allow(player_ptr, fis_ptr->k)) {
670                         fis_ptr->done = true;
671                         break;
672                     }
673
674                     *cp = fis_ptr->k;
675                     fis_ptr->item = true;
676                     fis_ptr->done = true;
677                     break;
678                 }
679             }
680
681             if (command_see) {
682                 screen_load();
683                 screen_save();
684             }
685
686             command_wrk = (USE_FLOOR);
687             break;
688         }
689         case '0':
690         case '1':
691         case '2':
692         case '3':
693         case '4':
694         case '5':
695         case '6':
696         case '7':
697         case '8':
698         case '9': {
699             if (command_wrk != USE_FLOOR) {
700                 if (!get_tag(player_ptr, &fis_ptr->k, fis_ptr->which, command_wrk, item_tester)) {
701                     bell();
702                     break;
703                 }
704
705                 if ((fis_ptr->k < INVEN_MAIN_HAND) ? !fis_ptr->inven : !fis_ptr->equip) {
706                     bell();
707                     break;
708                 }
709
710                 if (!get_item_okay(player_ptr, fis_ptr->k, item_tester)) {
711                     bell();
712                     break;
713                 }
714             } else {
715                 if (get_tag_floor(player_ptr->current_floor_ptr, &fis_ptr->k, fis_ptr->which, fis_ptr->floor_list, fis_ptr->floor_num)) {
716                     fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
717                 } else {
718                     bell();
719                     break;
720                 }
721             }
722
723             if (!get_item_allow(player_ptr, fis_ptr->k)) {
724                 fis_ptr->done = true;
725                 break;
726             }
727
728             *cp = fis_ptr->k;
729             fis_ptr->item = true;
730             fis_ptr->done = true;
731             fis_ptr->cur_tag = fis_ptr->which;
732             break;
733         }
734         case 'w': {
735             if (fis_ptr->force) {
736                 *cp = INVEN_FORCE;
737                 fis_ptr->item = true;
738                 fis_ptr->done = true;
739                 break;
740             }
741         }
742             /* Fall through */
743         default: {
744             bool tag_not_found = false;
745
746             if (command_wrk != USE_FLOOR) {
747                 if (!get_tag(player_ptr, &fis_ptr->k, fis_ptr->which, command_wrk, item_tester))
748                     tag_not_found = true;
749                 else if ((fis_ptr->k < INVEN_MAIN_HAND) ? !fis_ptr->inven : !fis_ptr->equip)
750                     tag_not_found = true;
751
752                 if (!tag_not_found)
753                     fis_ptr->cur_tag = fis_ptr->which;
754             } else {
755                 if (get_tag_floor(player_ptr->current_floor_ptr, &fis_ptr->k, fis_ptr->which, fis_ptr->floor_list, fis_ptr->floor_num)) {
756                     fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
757                     fis_ptr->cur_tag = fis_ptr->which;
758                 } else
759                     tag_not_found = true;
760             }
761
762             if (tag_not_found) {
763                 auto which = (char)tolower(fis_ptr->which);
764
765                 if (command_wrk == (USE_INVEN)) {
766                     if (which == '(')
767                         fis_ptr->k = fis_ptr->i1;
768                     else if (which == ')')
769                         fis_ptr->k = fis_ptr->i2;
770                     else
771                         fis_ptr->k = label_to_inventory(player_ptr, which);
772                 } else if (command_wrk == (USE_EQUIP)) {
773                     if (which == '(')
774                         fis_ptr->k = fis_ptr->e1;
775                     else if (which == ')')
776                         fis_ptr->k = fis_ptr->e2;
777                     else
778                         fis_ptr->k = label_to_equipment(player_ptr, which);
779                 } else if (command_wrk == USE_FLOOR) {
780                     if (which == '(')
781                         fis_ptr->k = 0;
782                     else if (which == ')')
783                         fis_ptr->k = fis_ptr->floor_num - 1;
784                     else
785                         fis_ptr->k = islower(which) ? A2I(which) : -1;
786                     if (fis_ptr->k < 0 || fis_ptr->k >= fis_ptr->floor_num || fis_ptr->k >= 23) {
787                         bell();
788                         break;
789                     }
790
791                     fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
792                 }
793             }
794
795             if ((command_wrk != USE_FLOOR) && !get_item_okay(player_ptr, fis_ptr->k, item_tester)) {
796                 bell();
797                 break;
798             }
799
800             auto ver = tag_not_found && isupper(fis_ptr->which);
801             if (ver && !verify(player_ptr, _("本当に", "Try"), fis_ptr->k)) {
802                 fis_ptr->done = true;
803                 break;
804             }
805
806             if (!get_item_allow(player_ptr, fis_ptr->k)) {
807                 fis_ptr->done = true;
808                 break;
809             }
810
811             *cp = fis_ptr->k;
812             fis_ptr->item = true;
813             fis_ptr->done = true;
814             break;
815         }
816         }
817     }
818
819     if (command_see) {
820         screen_load();
821         command_see = false;
822     }
823
824     if (fis_ptr->toggle)
825         toggle_inventory_equipment(player_ptr);
826
827     player_ptr->window_flags |= (PW_INVEN | PW_EQUIP);
828     handle_stuff(player_ptr);
829     prt("", 0, 0);
830     if (fis_ptr->oops && str)
831         msg_print(str);
832
833     if (fis_ptr->item) {
834         repeat_push(*cp);
835         if (command_cmd)
836             prev_tag = fis_ptr->cur_tag;
837         command_cmd = 0;
838     }
839
840     return fis_ptr->item;
841 }