OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Fix-Drain-Staff-Wand' into develop
[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 (inventory_slot_type i = INVEN_RARM; i < INVEN_TOTAL; i++)
185         if (owner_ptr->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     handle_stuff(owner_ptr);
208     test_inventory_floor(owner_ptr, fis_ptr);
209     fis_ptr->done = FALSE;
210     fis_ptr->item = FALSE;
211     fis_ptr->i1 = 0;
212     fis_ptr->i2 = INVEN_PACK - 1;
213     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(owner_ptr, fis_ptr->i1, fis_ptr->tval)))
214         fis_ptr->i1++;
215
216     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(owner_ptr, fis_ptr->i2, fis_ptr->tval)))
217         fis_ptr->i2--;
218
219     fis_ptr->e1 = INVEN_RARM;
220     fis_ptr->e2 = INVEN_TOTAL - 1;
221     test_equipment_floor(owner_ptr, fis_ptr);
222     if (has_two_handed_weapons(owner_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT))
223         fis_ptr->max_equip++;
224
225     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(owner_ptr, fis_ptr->e1, fis_ptr->tval)))
226         fis_ptr->e1++;
227
228     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(owner_ptr, fis_ptr->e2, fis_ptr->tval)))
229         fis_ptr->e2--;
230
231     if (fis_ptr->equip && has_two_handed_weapons(owner_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT)) {
232         if (has_right_hand_weapon(owner_ptr)) {
233             if (fis_ptr->e2 < INVEN_LARM)
234                 fis_ptr->e2 = INVEN_LARM;
235         } else if (has_left_hand_weapon(owner_ptr))
236             fis_ptr->e1 = INVEN_RARM;
237     }
238
239     fis_ptr->floor_num = 0;
240     if (fis_ptr->floor)
241         fis_ptr->floor_num = scan_floor_items(owner_ptr, fis_ptr->floor_list, owner_ptr->y, owner_ptr->x, 0x03, fis_ptr->tval);
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 == TRUE) || 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(owner_ptr);
295             fis_ptr->toggle = !fis_ptr->toggle;
296         }
297
298         owner_ptr->window |= (PW_INVEN | PW_EQUIP);
299         handle_stuff(owner_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(owner_ptr, fis_ptr->menu_line, fis_ptr->mode, fis_ptr->tval);
306         } else if (command_wrk == USE_EQUIP) {
307             fis_ptr->n1 = I2A(fis_ptr->e1 - INVEN_RARM);
308             fis_ptr->n2 = I2A(fis_ptr->e2 - INVEN_RARM);
309             if (command_see)
310                 get_item_label = show_equipment(owner_ptr, fis_ptr->menu_line, mode, fis_ptr->tval);
311         } else if (command_wrk == USE_FLOOR) {
312             int j = fis_ptr->floor_top;
313             fis_ptr->k = 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(owner_ptr, fis_ptr->menu_line, owner_ptr->y, owner_ptr->x, &fis_ptr->min_width, fis_ptr->tval);
318         }
319
320         if (command_wrk == USE_INVEN) {
321             sprintf(fis_ptr->out_val, _("持ち物:", "Inven:"));
322             if (!use_menu) {
323                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->i1), index_to_label(fis_ptr->i2));
324                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
325             }
326
327             if (!command_see && !use_menu)
328                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
329
330             if (fis_ptr->allow_equip) {
331                 if (!use_menu)
332                     strcat(fis_ptr->out_val, _(" '/' 装備品,", " / for Equip,"));
333                 else if (fis_ptr->allow_floor)
334                     strcat(fis_ptr->out_val, _(" '6' 装備品,", " 6 for Equip,"));
335                 else
336                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
337             }
338
339             if (fis_ptr->allow_floor) {
340                 if (!use_menu)
341                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
342                 else if (fis_ptr->allow_equip)
343                     strcat(fis_ptr->out_val, _(" '4' 床上,", " 4 for floor,"));
344                 else
345                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
346             }
347         } else if (command_wrk == (USE_EQUIP)) {
348             sprintf(fis_ptr->out_val, _("装備品:", "Equip:"));
349             if (!use_menu) {
350                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->e1), index_to_label(fis_ptr->e2));
351                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
352             }
353
354             if (!command_see && !use_menu)
355                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
356
357             if (fis_ptr->allow_inven) {
358                 if (!use_menu)
359                     strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
360                 else if (fis_ptr->allow_floor)
361                     strcat(fis_ptr->out_val, _(" '4' 持ち物,", " 4 for Inven,"));
362                 else
363                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
364             }
365
366             if (fis_ptr->allow_floor) {
367                 if (!use_menu)
368                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
369                 else if (fis_ptr->allow_inven)
370                     strcat(fis_ptr->out_val, _(" '6' 床上,", " 6 for floor,"));
371                 else
372                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
373             }
374         } else if (command_wrk == USE_FLOOR) {
375             sprintf(fis_ptr->out_val, _("床上:", "Floor:"));
376             if (!use_menu) {
377                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), fis_ptr->n1, fis_ptr->n2);
378                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
379             }
380
381             if (!command_see && !use_menu)
382                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
383
384             if (use_menu) {
385                 if (fis_ptr->allow_inven && fis_ptr->allow_equip) {
386                     strcat(fis_ptr->out_val, _(" '4' 装備品, '6' 持ち物,", " 4 for Equip, 6 for Inven,"));
387                 } else if (fis_ptr->allow_inven) {
388                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
389                 } else if (fis_ptr->allow_equip) {
390                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
391                 }
392             } else if (fis_ptr->allow_inven) {
393                 strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
394             } else if (fis_ptr->allow_equip) {
395                 strcat(fis_ptr->out_val, _(" '/'装備品,", " / for Equip,"));
396             }
397
398             if (command_see && !use_menu) {
399                 strcat(fis_ptr->out_val, _(" Enter 次,", " Enter for scroll down,"));
400             }
401         }
402
403         if (fis_ptr->force)
404             strcat(fis_ptr->out_val, _(" 'w'練気術,", " w for the Force,"));
405
406         strcat(fis_ptr->out_val, " ESC");
407         sprintf(fis_ptr->tmp_val, "(%s) %s", fis_ptr->out_val, pmt);
408         prt(fis_ptr->tmp_val, 0, 0);
409         fis_ptr->which = inkey();
410         if (use_menu) {
411             int max_line = 1;
412             if (command_wrk == USE_INVEN)
413                 max_line = fis_ptr->max_inven;
414             else if (command_wrk == USE_EQUIP)
415                 max_line = fis_ptr->max_equip;
416             else if (command_wrk == USE_FLOOR)
417                 max_line = MIN(23, fis_ptr->floor_num);
418             switch (fis_ptr->which) {
419             case ESCAPE:
420             case 'z':
421             case 'Z':
422             case '0': {
423                 fis_ptr->done = TRUE;
424                 break;
425             }
426             case '8':
427             case 'k':
428             case 'K': {
429                 fis_ptr->menu_line += (max_line - 1);
430                 break;
431             }
432             case '2':
433             case 'j':
434             case 'J': {
435                 fis_ptr->menu_line++;
436                 break;
437             }
438             case '4':
439             case 'h':
440             case 'H': {
441                 if (command_wrk == (USE_INVEN)) {
442                     if (fis_ptr->allow_floor)
443                         command_wrk = USE_FLOOR;
444                     else if (fis_ptr->allow_equip)
445                         command_wrk = USE_EQUIP;
446                     else {
447                         bell();
448                         break;
449                     }
450                 } else if (command_wrk == (USE_EQUIP)) {
451                     if (fis_ptr->allow_inven)
452                         command_wrk = USE_INVEN;
453                     else if (fis_ptr->allow_floor)
454                         command_wrk = USE_FLOOR;
455                     else {
456                         bell();
457                         break;
458                     }
459                 } else if (command_wrk == (USE_FLOOR)) {
460                     if (fis_ptr->allow_equip)
461                         command_wrk = USE_EQUIP;
462                     else if (fis_ptr->allow_inven)
463                         command_wrk = USE_INVEN;
464                     else {
465                         bell();
466                         break;
467                     }
468                 } else {
469                     bell();
470                     break;
471                 }
472
473                 if (command_see) {
474                     screen_load();
475                     screen_save();
476                 }
477
478                 if (command_wrk == USE_INVEN)
479                     max_line = fis_ptr->max_inven;
480                 else if (command_wrk == USE_EQUIP)
481                     max_line = fis_ptr->max_equip;
482                 else if (command_wrk == USE_FLOOR)
483                     max_line = MIN(23, fis_ptr->floor_num);
484
485                 if (fis_ptr->menu_line > max_line)
486                     fis_ptr->menu_line = max_line;
487
488                 break;
489             }
490             case '6':
491             case 'l':
492             case 'L': {
493                 if (command_wrk == (USE_INVEN)) {
494                     if (fis_ptr->allow_equip)
495                         command_wrk = USE_EQUIP;
496                     else if (fis_ptr->allow_floor)
497                         command_wrk = USE_FLOOR;
498                     else {
499                         bell();
500                         break;
501                     }
502                 } else if (command_wrk == (USE_EQUIP)) {
503                     if (fis_ptr->allow_floor)
504                         command_wrk = USE_FLOOR;
505                     else if (fis_ptr->allow_inven)
506                         command_wrk = USE_INVEN;
507                     else {
508                         bell();
509                         break;
510                     }
511                 } else if (command_wrk == (USE_FLOOR)) {
512                     if (fis_ptr->allow_inven)
513                         command_wrk = USE_INVEN;
514                     else if (fis_ptr->allow_equip)
515                         command_wrk = USE_EQUIP;
516                     else {
517                         bell();
518                         break;
519                     }
520                 } else {
521                     bell();
522                     break;
523                 }
524
525                 if (command_see) {
526                     screen_load();
527                     screen_save();
528                 }
529
530                 if (command_wrk == USE_INVEN)
531                     max_line = fis_ptr->max_inven;
532                 else if (command_wrk == USE_EQUIP)
533                     max_line = fis_ptr->max_equip;
534                 else if (command_wrk == USE_FLOOR)
535                     max_line = MIN(23, fis_ptr->floor_num);
536
537                 if (fis_ptr->menu_line > max_line)
538                     fis_ptr->menu_line = max_line;
539
540                 break;
541             }
542             case 'x':
543             case 'X':
544             case '\r':
545             case '\n': {
546                 if (command_wrk == USE_FLOOR)
547                     *cp = -get_item_label;
548                 else {
549                     if (!get_item_okay(owner_ptr, get_item_label, fis_ptr->tval)) {
550                         bell();
551                         break;
552                     }
553
554                     if (!get_item_allow(owner_ptr, get_item_label)) {
555                         fis_ptr->done = TRUE;
556                         break;
557                     }
558
559                     *cp = get_item_label;
560                 }
561
562                 fis_ptr->item = TRUE;
563                 fis_ptr->done = TRUE;
564                 break;
565             }
566             case 'w': {
567                 if (fis_ptr->force) {
568                     *cp = INVEN_FORCE;
569                     fis_ptr->item = TRUE;
570                     fis_ptr->done = TRUE;
571                     break;
572                 }
573             }
574             }
575
576             if (fis_ptr->menu_line > max_line)
577                 fis_ptr->menu_line -= max_line;
578
579             continue;
580         }
581
582         switch (fis_ptr->which) {
583         case ESCAPE: {
584             fis_ptr->done = TRUE;
585             break;
586         }
587         case '*':
588         case '?':
589         case ' ': {
590             if (command_see) {
591                 command_see = FALSE;
592                 screen_load();
593             } else {
594                 screen_save();
595                 command_see = TRUE;
596             }
597
598             break;
599         }
600         case '\n':
601         case '\r':
602         case '+': {
603             int i;
604             OBJECT_IDX o_idx;
605             grid_type *g_ptr = &owner_ptr->current_floor_ptr->grid_array[owner_ptr->y][owner_ptr->x];
606             if (command_wrk != (USE_FLOOR))
607                 break;
608
609             o_idx = g_ptr->o_idx;
610             if (!(o_idx && owner_ptr->current_floor_ptr->o_list[o_idx].next_o_idx))
611                 break;
612
613             excise_object_idx(owner_ptr->current_floor_ptr, o_idx);
614             i = g_ptr->o_idx;
615             while (owner_ptr->current_floor_ptr->o_list[i].next_o_idx)
616                 i = owner_ptr->current_floor_ptr->o_list[i].next_o_idx;
617
618             owner_ptr->current_floor_ptr->o_list[i].next_o_idx = o_idx;
619             fis_ptr->floor_num = scan_floor_items(owner_ptr, fis_ptr->floor_list, owner_ptr->y, owner_ptr->x, 0x03, fis_ptr->tval);
620             if (command_see) {
621                 screen_load();
622                 screen_save();
623             }
624
625             break;
626         }
627         case '/': {
628             if (command_wrk == (USE_INVEN)) {
629                 if (!fis_ptr->allow_equip) {
630                     bell();
631                     break;
632                 }
633                 command_wrk = (USE_EQUIP);
634             } else if (command_wrk == (USE_EQUIP)) {
635                 if (!fis_ptr->allow_inven) {
636                     bell();
637                     break;
638                 }
639                 command_wrk = (USE_INVEN);
640             } else if (command_wrk == (USE_FLOOR)) {
641                 if (fis_ptr->allow_inven) {
642                     command_wrk = (USE_INVEN);
643                 } else if (fis_ptr->allow_equip) {
644                     command_wrk = (USE_EQUIP);
645                 } else {
646                     bell();
647                     break;
648                 }
649             }
650
651             if (command_see) {
652                 screen_load();
653                 screen_save();
654             }
655
656             break;
657         }
658         case '-': {
659             if (!fis_ptr->allow_floor) {
660                 bell();
661                 break;
662             }
663
664             if (fis_ptr->floor_num == 1) {
665                 if ((command_wrk == (USE_FLOOR)) || (!carry_query_flag)) {
666                     fis_ptr->k = 0 - fis_ptr->floor_list[0];
667                     if (!get_item_allow(owner_ptr, fis_ptr->k)) {
668                         fis_ptr->done = TRUE;
669                         break;
670                     }
671
672                     *cp = fis_ptr->k;
673                     fis_ptr->item = TRUE;
674                     fis_ptr->done = TRUE;
675                     break;
676                 }
677             }
678
679             if (command_see) {
680                 screen_load();
681                 screen_save();
682             }
683
684             command_wrk = (USE_FLOOR);
685             break;
686         }
687         case '0':
688         case '1':
689         case '2':
690         case '3':
691         case '4':
692         case '5':
693         case '6':
694         case '7':
695         case '8':
696         case '9': {
697             if (command_wrk != USE_FLOOR) {
698                 if (!get_tag(owner_ptr, &fis_ptr->k, fis_ptr->which, command_wrk, fis_ptr->tval)) {
699                     bell();
700                     break;
701                 }
702
703                 if ((fis_ptr->k < INVEN_RARM) ? !fis_ptr->inven : !fis_ptr->equip) {
704                     bell();
705                     break;
706                 }
707
708                 if (!get_item_okay(owner_ptr, fis_ptr->k, fis_ptr->tval)) {
709                     bell();
710                     break;
711                 }
712             } else {
713                 if (get_tag_floor(owner_ptr->current_floor_ptr, &fis_ptr->k, fis_ptr->which, fis_ptr->floor_list, fis_ptr->floor_num)) {
714                     fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
715                 } else {
716                     bell();
717                     break;
718                 }
719             }
720
721             if (!get_item_allow(owner_ptr, fis_ptr->k)) {
722                 fis_ptr->done = TRUE;
723                 break;
724             }
725
726             *cp = fis_ptr->k;
727             fis_ptr->item = TRUE;
728             fis_ptr->done = TRUE;
729             fis_ptr->cur_tag = fis_ptr->which;
730             break;
731         }
732         case 'w': {
733             if (fis_ptr->force) {
734                 *cp = INVEN_FORCE;
735                 fis_ptr->item = TRUE;
736                 fis_ptr->done = TRUE;
737                 break;
738             }
739         }
740             /* Fall through */
741         default: {
742             int ver;
743             if (command_wrk != USE_FLOOR) {
744                 bool not_found = FALSE;
745                 if (!get_tag(owner_ptr, &fis_ptr->k, fis_ptr->which, command_wrk, fis_ptr->tval))
746                     not_found = TRUE;
747                 else if ((fis_ptr->k < INVEN_RARM) ? !fis_ptr->inven : !fis_ptr->equip)
748                     not_found = TRUE;
749                 else if (!get_item_okay(owner_ptr, fis_ptr->k, fis_ptr->tval))
750                     not_found = TRUE;
751
752                 if (!not_found) {
753                     *cp = fis_ptr->k;
754                     fis_ptr->item = TRUE;
755                     fis_ptr->done = TRUE;
756                     fis_ptr->cur_tag = fis_ptr->which;
757                     break;
758                 }
759             } else {
760                 if (get_tag_floor(owner_ptr->current_floor_ptr, &fis_ptr->k, fis_ptr->which, fis_ptr->floor_list, fis_ptr->floor_num)) {
761                     fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
762                     *cp = fis_ptr->k;
763                     fis_ptr->item = TRUE;
764                     fis_ptr->done = TRUE;
765                     fis_ptr->cur_tag = fis_ptr->which;
766                     break;
767                 }
768             }
769
770             ver = isupper(fis_ptr->which);
771             fis_ptr->which = (char)tolower(fis_ptr->which);
772             if (command_wrk == (USE_INVEN)) {
773                 if (fis_ptr->which == '(')
774                     fis_ptr->k = fis_ptr->i1;
775                 else if (fis_ptr->which == ')')
776                     fis_ptr->k = fis_ptr->i2;
777                 else
778                     fis_ptr->k = label_to_inventory(owner_ptr, fis_ptr->which);
779             } else if (command_wrk == (USE_EQUIP)) {
780                 if (fis_ptr->which == '(')
781                     fis_ptr->k = fis_ptr->e1;
782                 else if (fis_ptr->which == ')')
783                     fis_ptr->k = fis_ptr->e2;
784                 else
785                     fis_ptr->k = label_to_equipment(owner_ptr, fis_ptr->which);
786             } else if (command_wrk == USE_FLOOR) {
787                 if (fis_ptr->which == '(')
788                     fis_ptr->k = 0;
789                 else if (fis_ptr->which == ')')
790                     fis_ptr->k = fis_ptr->floor_num - 1;
791                 else
792                     fis_ptr->k = islower(fis_ptr->which) ? A2I(fis_ptr->which) : -1;
793                 if (fis_ptr->k < 0 || fis_ptr->k >= fis_ptr->floor_num || fis_ptr->k >= 23) {
794                     bell();
795                     break;
796                 }
797
798                 fis_ptr->k = 0 - fis_ptr->floor_list[fis_ptr->k];
799             }
800
801             if ((command_wrk != USE_FLOOR) && !get_item_okay(owner_ptr, fis_ptr->k, fis_ptr->tval)) {
802                 bell();
803                 break;
804             }
805
806             if (ver && !verify(owner_ptr, _("本当に", "Try"), fis_ptr->k)) {
807                 fis_ptr->done = TRUE;
808                 break;
809             }
810
811             if (!get_item_allow(owner_ptr, fis_ptr->k)) {
812                 fis_ptr->done = TRUE;
813                 break;
814             }
815
816             *cp = fis_ptr->k;
817             fis_ptr->item = TRUE;
818             fis_ptr->done = TRUE;
819             break;
820         }
821         }
822     }
823
824     if (command_see) {
825         screen_load();
826         command_see = FALSE;
827     }
828
829     fis_ptr->tval = 0;
830     item_tester_hook = NULL;
831     if (fis_ptr->toggle)
832         toggle_inventory_equipment(owner_ptr);
833
834     owner_ptr->window |= (PW_INVEN | PW_EQUIP);
835     handle_stuff(owner_ptr);
836     prt("", 0, 0);
837     if (fis_ptr->oops && str)
838         msg_print(str);
839
840     if (fis_ptr->item) {
841         repeat_push(*cp);
842         if (command_cmd)
843             prev_tag = fis_ptr->cur_tag;
844         command_cmd = 0;
845     }
846
847     return fis_ptr->item;
848 }