OSDN Git Service

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