OSDN Git Service

[Fix] クイックメッセージの挙動が以前と異なる
[hengband/hengband.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     bool flag = FALSE;
84     item_use_flag use_flag = (*fis_ptr->cp >= INVEN_MAIN_HAND) ? USE_EQUIP : USE_INVEN;
85
86     flag |= !get_tag(owner_ptr, &fis_ptr->k, *prev_tag, use_flag, fis_ptr->tval);
87     flag |= !get_item_okay(owner_ptr, fis_ptr->k, fis_ptr->tval);
88
89     if (fis_ptr->k < INVEN_MAIN_HAND)
90         flag |= !fis_ptr->inven;
91     else
92         flag |= !fis_ptr->equip;
93
94     if (!flag) {
95         *prev_tag = '\0';
96         return FALSE;
97     }
98
99     *fis_ptr->cp = fis_ptr->k;
100     fis_ptr->tval = TV_NONE;
101     item_tester_hook = NULL;
102     command_cmd = 0;
103     return TRUE;
104 }
105
106 /*!
107  * @brief インベントリのアイテムにタグ付けがされているかの調査処理 (のはず)
108  * @param owner_ptr プレーヤーへの参照ポインタ
109  * @param fis_ptr 床上アイテムへの参照ポインタ
110  * @param prev_tag 前回選択したアイテムのタグ (のはず)
111  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
112  */
113 static bool check_floor_item_tag_inventory(player_type *owner_ptr, fis_type *fis_ptr, char *prev_tag)
114 {
115     if ((!fis_ptr->inven || (*fis_ptr->cp < 0) || (*fis_ptr->cp >= INVEN_PACK))
116         && (!fis_ptr->equip || (*fis_ptr->cp < INVEN_MAIN_HAND) || (*fis_ptr->cp >= INVEN_TOTAL)))
117         return FALSE;
118
119     if (get_floor_item_tag_inventory(owner_ptr, fis_ptr, prev_tag))
120         return TRUE;
121
122     if (get_item_okay(owner_ptr, *fis_ptr->cp, fis_ptr->tval)) {
123         fis_ptr->tval = 0;
124         item_tester_hook = NULL;
125         command_cmd = 0;
126         return TRUE;
127     }
128
129     return FALSE;
130 }
131
132 /*!
133  * @brief 床上アイテムにタグ付けがされているかの調査処理 (のはず)
134  * @param owner_ptr プレーヤーへの参照ポインタ
135  * @param fis_ptr 床上アイテムへの参照ポインタ
136  * @param prev_tag 前回選択したアイテムのタグ (のはず)
137  * @return プレイヤーによりアイテムが選択されたならTRUEを返す
138  */
139 static bool check_floor_item_tag(player_type *owner_ptr, fis_type *fis_ptr, char *prev_tag)
140 {
141     if (!repeat_pull(fis_ptr->cp))
142         return FALSE;
143
144     if (fis_ptr->force && (*fis_ptr->cp == INVEN_FORCE)) {
145         fis_ptr->tval = 0;
146         item_tester_hook = NULL;
147         command_cmd = 0;
148         return TRUE;
149     }
150
151     if (check_floor_item_tag_aux(owner_ptr, fis_ptr, prev_tag))
152         return TRUE;
153
154     return check_floor_item_tag_inventory(owner_ptr, fis_ptr, prev_tag);
155 }
156
157 /*!
158  * @brief インベントリ内のアイテムが妥当かを判定する
159  * @param owner_ptr プレーヤーへの参照ポインタ
160  * @param fis_ptr 床上アイテムへの参照ポインタ
161  * @return なし
162  */
163 static void test_inventory_floor(player_type *owner_ptr, fis_type *fis_ptr)
164 {
165     if (!fis_ptr->inven) {
166         fis_ptr->i2 = -1;
167         return;
168     }
169
170     if (!use_menu)
171         return;
172
173     for (int i = 0; i < INVEN_PACK; i++)
174         if (item_tester_okay(owner_ptr, &owner_ptr->inventory_list[i], fis_ptr->tval) || (fis_ptr->mode & USE_FULL))
175             fis_ptr->max_inven++;
176 }
177
178 /*!
179  * @brief 装備品がが妥当かを判定する
180  * @param owner_ptr プレーヤーへの参照ポインタ
181  * @param fis_ptr 床上アイテムへの参照ポインタ
182  * @return なし
183  */
184 static void test_equipment_floor(player_type *owner_ptr, fis_type *fis_ptr)
185 {
186     if (!fis_ptr->equip) {
187         fis_ptr->e2 = -1;
188         return;
189     }
190
191     if (!use_menu)
192         return;
193
194     for (inventory_slot_type i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++)
195         if (owner_ptr->select_ring_slot ? is_ring_slot(i)
196                                         : item_tester_okay(owner_ptr, &owner_ptr->inventory_list[i], fis_ptr->tval) || (fis_ptr->mode & USE_FULL))
197             fis_ptr->max_equip++;
198 }
199
200 /*!
201  * @brief オブジェクト選択の汎用関数(床上アイテム用) /
202  * Let the user select an item, save its "index"
203  * @param cp 選択したオブジェクトのIDを返す。
204  * @param pmt 選択目的のメッセージ
205  * @param str 選択できるオブジェクトがない場合のキャンセルメッセージ
206  * @param mode オプションフラグ
207  * @return プレイヤーによりアイテムが選択されたならTRUEを返す。/
208  */
209 bool get_item_floor(player_type *owner_ptr, COMMAND_CODE *cp, concptr pmt, concptr str, BIT_FLAGS mode, tval_type tval)
210 {
211     fis_type tmp_fis;
212     fis_type *fis_ptr = initialize_fis_type(&tmp_fis, cp, mode, tval);
213     static char prev_tag = '\0';
214     if (check_floor_item_tag(owner_ptr, fis_ptr, &prev_tag))
215         return TRUE;
216
217     msg_print(NULL);
218     handle_stuff(owner_ptr);
219     test_inventory_floor(owner_ptr, fis_ptr);
220     fis_ptr->done = FALSE;
221     fis_ptr->item = FALSE;
222     fis_ptr->i1 = 0;
223     fis_ptr->i2 = INVEN_PACK - 1;
224     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(owner_ptr, fis_ptr->i1, fis_ptr->tval)))
225         fis_ptr->i1++;
226
227     while ((fis_ptr->i1 <= fis_ptr->i2) && (!get_item_okay(owner_ptr, fis_ptr->i2, fis_ptr->tval)))
228         fis_ptr->i2--;
229
230     fis_ptr->e1 = INVEN_MAIN_HAND;
231     fis_ptr->e2 = INVEN_TOTAL - 1;
232     test_equipment_floor(owner_ptr, fis_ptr);
233     if (has_two_handed_weapons(owner_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT))
234         fis_ptr->max_equip++;
235
236     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(owner_ptr, fis_ptr->e1, fis_ptr->tval)))
237         fis_ptr->e1++;
238
239     while ((fis_ptr->e1 <= fis_ptr->e2) && (!get_item_okay(owner_ptr, fis_ptr->e2, fis_ptr->tval)))
240         fis_ptr->e2--;
241
242     if (fis_ptr->equip && has_two_handed_weapons(owner_ptr) && !(fis_ptr->mode & IGNORE_BOTHHAND_SLOT)) {
243         if (can_attack_with_main_hand(owner_ptr)) {
244             if (fis_ptr->e2 < INVEN_SUB_HAND)
245                 fis_ptr->e2 = INVEN_SUB_HAND;
246         } else if (can_attack_with_sub_hand(owner_ptr))
247             fis_ptr->e1 = INVEN_MAIN_HAND;
248     }
249
250     fis_ptr->floor_num = 0;
251     if (fis_ptr->floor)
252         fis_ptr->floor_num = scan_floor_items(owner_ptr, fis_ptr->floor_list, owner_ptr->y, owner_ptr->x, 0x03, fis_ptr->tval);
253
254     if ((mode & USE_INVEN) && (fis_ptr->i1 <= fis_ptr->i2))
255         fis_ptr->allow_inven = TRUE;
256
257     if ((mode & USE_EQUIP) && (fis_ptr->e1 <= fis_ptr->e2))
258         fis_ptr->allow_equip = TRUE;
259
260     if ((mode & USE_FLOOR) && (fis_ptr->floor_num))
261         fis_ptr->allow_floor = TRUE;
262
263     if (!fis_ptr->allow_inven && !fis_ptr->allow_equip && !fis_ptr->allow_floor) {
264         command_see = FALSE;
265         fis_ptr->oops = TRUE;
266         fis_ptr->done = TRUE;
267
268         if (fis_ptr->force) {
269             *cp = INVEN_FORCE;
270             fis_ptr->item = TRUE;
271         }
272     } else {
273         if (command_see && (command_wrk == USE_EQUIP) && fis_ptr->allow_equip)
274             command_wrk = USE_EQUIP;
275         else if (fis_ptr->allow_inven)
276             command_wrk = USE_INVEN;
277         else if (fis_ptr->allow_equip)
278             command_wrk = USE_EQUIP;
279         else if (fis_ptr->allow_floor)
280             command_wrk = USE_FLOOR;
281     }
282
283     /* 追加オプション(always_show_list)が設定されている場合は常に一覧を表示する */
284     if ((always_show_list == TRUE) || use_menu)
285         command_see = TRUE;
286
287     if (command_see)
288         screen_save();
289
290     while (!fis_ptr->done) {
291         int ni = 0;
292         int ne = 0;
293         for (int i = 0; i < 8; i++) {
294             if (!angband_term[i])
295                 continue;
296
297             if (window_flag[i] & PW_INVEN)
298                 ni++;
299
300             if (window_flag[i] & PW_EQUIP)
301                 ne++;
302         }
303
304         if ((command_wrk == (USE_EQUIP) && ni && !ne) || (command_wrk == (USE_INVEN) && !ni && ne)) {
305             toggle_inventory_equipment(owner_ptr);
306             fis_ptr->toggle = !fis_ptr->toggle;
307         }
308
309         owner_ptr->window |= (PW_INVEN | PW_EQUIP);
310         handle_stuff(owner_ptr);
311         COMMAND_CODE get_item_label = 0;
312         if (command_wrk == USE_INVEN) {
313             fis_ptr->n1 = I2A(fis_ptr->i1);
314             fis_ptr->n2 = I2A(fis_ptr->i2);
315             if (command_see)
316                 get_item_label = show_inventory(owner_ptr, fis_ptr->menu_line, fis_ptr->mode, fis_ptr->tval);
317         } else if (command_wrk == USE_EQUIP) {
318             fis_ptr->n1 = I2A(fis_ptr->e1 - INVEN_MAIN_HAND);
319             fis_ptr->n2 = I2A(fis_ptr->e2 - INVEN_MAIN_HAND);
320             if (command_see)
321                 get_item_label = show_equipment(owner_ptr, fis_ptr->menu_line, mode, fis_ptr->tval);
322         } else if (command_wrk == USE_FLOOR) {
323             int j = fis_ptr->floor_top;
324             fis_ptr->k = MIN(fis_ptr->floor_top + 23, fis_ptr->floor_num) - 1;
325             fis_ptr->n1 = I2A(j - fis_ptr->floor_top); // TODO: 常に'0'になる。どんな意図でこのようなコードになっているのか不明.
326             fis_ptr->n2 = I2A(fis_ptr->k - fis_ptr->floor_top);
327             if (command_see)
328                 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);
329         }
330
331         if (command_wrk == USE_INVEN) {
332             sprintf(fis_ptr->out_val, _("持ち物:", "Inven:"));
333             if (!use_menu) {
334                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->i1), index_to_label(fis_ptr->i2));
335                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
336             }
337
338             if (!command_see && !use_menu)
339                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
340
341             if (fis_ptr->allow_equip) {
342                 if (!use_menu)
343                     strcat(fis_ptr->out_val, _(" '/' 装備品,", " / for Equip,"));
344                 else if (fis_ptr->allow_floor)
345                     strcat(fis_ptr->out_val, _(" '6' 装備品,", " 6 for Equip,"));
346                 else
347                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
348             }
349
350             if (fis_ptr->allow_floor) {
351                 if (!use_menu)
352                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
353                 else if (fis_ptr->allow_equip)
354                     strcat(fis_ptr->out_val, _(" '4' 床上,", " 4 for floor,"));
355                 else
356                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
357             }
358         } else if (command_wrk == (USE_EQUIP)) {
359             sprintf(fis_ptr->out_val, _("装備品:", "Equip:"));
360             if (!use_menu) {
361                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(fis_ptr->e1), index_to_label(fis_ptr->e2));
362                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
363             }
364
365             if (!command_see && !use_menu)
366                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
367
368             if (fis_ptr->allow_inven) {
369                 if (!use_menu)
370                     strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
371                 else if (fis_ptr->allow_floor)
372                     strcat(fis_ptr->out_val, _(" '4' 持ち物,", " 4 for Inven,"));
373                 else
374                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
375             }
376
377             if (fis_ptr->allow_floor) {
378                 if (!use_menu)
379                     strcat(fis_ptr->out_val, _(" '-'床上,", " - for floor,"));
380                 else if (fis_ptr->allow_inven)
381                     strcat(fis_ptr->out_val, _(" '6' 床上,", " 6 for floor,"));
382                 else
383                     strcat(fis_ptr->out_val, _(" '4'or'6' 床上,", " 4 or 6 for floor,"));
384             }
385         } else if (command_wrk == USE_FLOOR) {
386             sprintf(fis_ptr->out_val, _("床上:", "Floor:"));
387             if (!use_menu) {
388                 sprintf(fis_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), fis_ptr->n1, fis_ptr->n2);
389                 strcat(fis_ptr->out_val, fis_ptr->tmp_val);
390             }
391
392             if (!command_see && !use_menu)
393                 strcat(fis_ptr->out_val, _(" '*'一覧,", " * to see,"));
394
395             if (use_menu) {
396                 if (fis_ptr->allow_inven && fis_ptr->allow_equip) {
397                     strcat(fis_ptr->out_val, _(" '4' 装備品, '6' 持ち物,", " 4 for Equip, 6 for Inven,"));
398                 } else if (fis_ptr->allow_inven) {
399                     strcat(fis_ptr->out_val, _(" '4'or'6' 持ち物,", " 4 or 6 for Inven,"));
400                 } else if (fis_ptr->allow_equip) {
401                     strcat(fis_ptr->out_val, _(" '4'or'6' 装備品,", " 4 or 6 for Equip,"));
402                 }
403             } else if (fis_ptr->allow_inven) {
404                 strcat(fis_ptr->out_val, _(" '/' 持ち物,", " / for Inven,"));
405             } else if (fis_ptr->allow_equip) {
406                 strcat(fis_ptr->out_val, _(" '/'装備品,", " / for Equip,"));
407             }
408
409             if (command_see && !use_menu) {
410                 strcat(fis_ptr->out_val, _(" Enter 次,", " Enter for scroll down,"));
411             }
412         }
413
414         if (fis_ptr->force)
415             strcat(fis_ptr->out_val, _(" 'w'練気術,", " w for the Force,"));
416
417         strcat(fis_ptr->out_val, " ESC");
418         sprintf(fis_ptr->tmp_val, "(%s) %s", fis_ptr->out_val, pmt);
419         prt(fis_ptr->tmp_val, 0, 0);
420         fis_ptr->which = inkey();
421         if (use_menu) {
422             int max_line = 1;
423             if (command_wrk == USE_INVEN)
424                 max_line = fis_ptr->max_inven;
425             else if (command_wrk == USE_EQUIP)
426                 max_line = fis_ptr->max_equip;
427             else if (command_wrk == USE_FLOOR)
428                 max_line = MIN(23, fis_ptr->floor_num);
429             switch (fis_ptr->which) {
430             case ESCAPE:
431             case 'z':
432             case 'Z':
433             case '0': {
434                 fis_ptr->done = TRUE;
435                 break;
436             }
437             case '8':
438             case 'k':
439             case 'K': {
440                 fis_ptr->menu_line += (max_line - 1);
441                 break;
442             }
443             case '2':
444             case 'j':
445             case 'J': {
446                 fis_ptr->menu_line++;
447                 break;
448             }
449             case '4':
450             case 'h':
451             case 'H': {
452                 if (command_wrk == (USE_INVEN)) {
453                     if (fis_ptr->allow_floor)
454                         command_wrk = USE_FLOOR;
455                     else if (fis_ptr->allow_equip)
456                         command_wrk = USE_EQUIP;
457                     else {
458                         bell();
459                         break;
460                     }
461                 } else if (command_wrk == (USE_EQUIP)) {
462                     if (fis_ptr->allow_inven)
463                         command_wrk = USE_INVEN;
464                     else if (fis_ptr->allow_floor)
465                         command_wrk = USE_FLOOR;
466                     else {
467                         bell();
468                         break;
469                     }
470                 } else if (command_wrk == (USE_FLOOR)) {
471                     if (fis_ptr->allow_equip)
472                         command_wrk = USE_EQUIP;
473                     else if (fis_ptr->allow_inven)
474                         command_wrk = USE_INVEN;
475                     else {
476                         bell();
477                         break;
478                     }
479                 } else {
480                     bell();
481                     break;
482                 }
483
484                 if (command_see) {
485                     screen_load();
486                     screen_save();
487                 }
488
489                 if (command_wrk == USE_INVEN)
490                     max_line = fis_ptr->max_inven;
491                 else if (command_wrk == USE_EQUIP)
492                     max_line = fis_ptr->max_equip;
493                 else if (command_wrk == USE_FLOOR)
494                     max_line = MIN(23, fis_ptr->floor_num);
495
496                 if (fis_ptr->menu_line > max_line)
497                     fis_ptr->menu_line = max_line;
498
499                 break;
500             }
501             case '6':
502             case 'l':
503             case 'L': {
504                 if (command_wrk == (USE_INVEN)) {
505                     if (fis_ptr->allow_equip)
506                         command_wrk = USE_EQUIP;
507                     else if (fis_ptr->allow_floor)
508                         command_wrk = USE_FLOOR;
509                     else {
510                         bell();
511                         break;
512                     }
513                 } else if (command_wrk == (USE_EQUIP)) {
514                     if (fis_ptr->allow_floor)
515                         command_wrk = USE_FLOOR;
516                     else if (fis_ptr->allow_inven)
517                         command_wrk = USE_INVEN;
518                     else {
519                         bell();
520                         break;
521                     }
522                 } else if (command_wrk == (USE_FLOOR)) {
523                     if (fis_ptr->allow_inven)
524                         command_wrk = USE_INVEN;
525                     else if (fis_ptr->allow_equip)
526                         command_wrk = USE_EQUIP;
527                     else {
528                         bell();
529                         break;
530                     }
531                 } else {
532                     bell();
533                     break;
534                 }
535
536                 if (command_see) {
537                     screen_load();
538                     screen_save();
539                 }
540
541                 if (command_wrk == USE_INVEN)
542                     max_line = fis_ptr->max_inven;
543                 else if (command_wrk == USE_EQUIP)
544                     max_line = fis_ptr->max_equip;
545                 else if (command_wrk == USE_FLOOR)
546                     max_line = MIN(23, fis_ptr->floor_num);
547
548                 if (fis_ptr->menu_line > max_line)
549                     fis_ptr->menu_line = max_line;
550
551                 break;
552             }
553             case 'x':
554             case 'X':
555             case '\r':
556             case '\n': {
557                 if (command_wrk == USE_FLOOR)
558                     *cp = -get_item_label;
559                 else {
560                     if (!get_item_okay(owner_ptr, get_item_label, fis_ptr->tval)) {
561                         bell();
562                         break;
563                     }
564
565                     if (!get_item_allow(owner_ptr, get_item_label)) {
566                         fis_ptr->done = TRUE;
567                         break;
568                     }
569
570                     *cp = get_item_label;
571                 }
572
573                 fis_ptr->item = TRUE;
574                 fis_ptr->done = TRUE;
575                 break;
576             }
577             case 'w': {
578                 if (fis_ptr->force) {
579                     *cp = INVEN_FORCE;
580                     fis_ptr->item = TRUE;
581                     fis_ptr->done = TRUE;
582                     break;
583                 }
584             }
585             }
586
587             if (fis_ptr->menu_line > max_line)
588                 fis_ptr->menu_line -= max_line;
589
590             continue;
591         }
592
593         switch (fis_ptr->which) {
594         case ESCAPE: {
595             fis_ptr->done = TRUE;
596             break;
597         }
598         case '*':
599         case '?':
600         case ' ': {
601             if (command_see) {
602                 command_see = FALSE;
603                 screen_load();
604             } else {
605                 screen_save();
606                 command_see = TRUE;
607             }
608
609             break;
610         }
611         case '\n':
612         case '\r':
613         case '+': {
614             int i;
615             OBJECT_IDX o_idx;
616             grid_type *g_ptr = &owner_ptr->current_floor_ptr->grid_array[owner_ptr->y][owner_ptr->x];
617             if (command_wrk != (USE_FLOOR))
618                 break;
619
620             o_idx = g_ptr->o_idx;
621             if (!(o_idx && owner_ptr->current_floor_ptr->o_list[o_idx].next_o_idx))
622                 break;
623
624             excise_object_idx(owner_ptr->current_floor_ptr, o_idx);
625             i = g_ptr->o_idx;
626             while (owner_ptr->current_floor_ptr->o_list[i].next_o_idx)
627                 i = owner_ptr->current_floor_ptr->o_list[i].next_o_idx;
628
629             owner_ptr->current_floor_ptr->o_list[i].next_o_idx = o_idx;
630             fis_ptr->floor_num = scan_floor_items(owner_ptr, fis_ptr->floor_list, owner_ptr->y, owner_ptr->x, 0x03, 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 |= (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 }