OSDN Git Service

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