OSDN Git Service

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