OSDN Git Service

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