OSDN Git Service

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