1 #include "inventory/item-getter.h"
2 #include "core/stuff-handler.h"
3 #include "floor/floor.h"
4 #include "game-option/input-options.h"
5 #include "game-option/option-flags.h"
6 #include "game-option/text-display-options.h"
8 #include "inventory/floor-item-getter.h"
9 #include "inventory/inventory-util.h"
10 #include "inventory/item-selection-util.h"
11 #include "io/command-repeater.h"
12 #include "io/input-key-acceptor.h"
13 #include "io/input-key-requester.h"
14 #include "main/sound-of-music.h"
15 #include "object/item-tester-hooker.h"
16 #include "object/item-use-flags.h"
17 #include "object/object-info.h"
18 #include "object/object-mark-types.h"
19 #include "term/gameterm.h"
20 #include "term/screen-processor.h"
21 #include "util/int-char-converter.h"
22 #include "view/display-inventory.h"
23 #include "view/display-messages.h"
24 #include "view/display-sub-windows.h"
27 * @brief オブジェクト選択の汎用関数 / General function for the selection of item
28 * Let the user select an item, save its "index"
29 * @param owner_ptr プレーヤーへの参照ポインタ
30 * @param cp 選択したオブジェクトのID
31 * @param pmt 選択目的のメッセージ
32 * @param str 選択できるオブジェクトがない場合のキャンセルメッセージ
33 * @param mode オプションフラグ
34 * @return プレイヤーによりアイテムが選択されたならTRUEを返す
35 * Return TRUE only if an acceptable item was chosen by the user
37 bool get_item(player_type *owner_ptr, OBJECT_IDX *cp, concptr pmt, concptr str, BIT_FLAGS mode, tval_type tval)
39 static char prev_tag = '\0'; // TODO: repeat_pull の中だけポインタにする
40 if (easy_floor || use_menu)
41 return get_item_floor(owner_ptr, cp, pmt, str, mode, tval);
43 item_selection_type tmp_selection;
44 item_selection_type *item_selection_ptr = initialize_item_selection_type(&tmp_selection, cp, mode, tval);
45 if (item_selection_ptr->mode & USE_EQUIP)
46 item_selection_ptr->equip = TRUE;
48 if (item_selection_ptr->mode & USE_INVEN)
49 item_selection_ptr->inven = TRUE;
51 if (item_selection_ptr->mode & USE_FLOOR)
52 item_selection_ptr->floor = TRUE;
54 if (repeat_pull(item_selection_ptr->cp)) {
55 if (item_selection_ptr->mode & USE_FORCE && (*item_selection_ptr->cp == INVEN_FORCE)) {
56 item_selection_ptr->tval = 0;
57 item_tester_hook = NULL;
60 } else if (item_selection_ptr->floor && (*item_selection_ptr->cp < 0)) {
62 item_selection_ptr->k = 0 - (*item_selection_ptr->cp);
63 o_ptr = &owner_ptr->current_floor_ptr->o_list[item_selection_ptr->k];
64 if (item_tester_okay(owner_ptr, o_ptr, item_selection_ptr->tval) || (item_selection_ptr->mode & USE_FULL)) {
65 item_selection_ptr->tval = 0;
66 item_tester_hook = NULL;
70 } else if ((item_selection_ptr->inven && (*item_selection_ptr->cp >= 0) && (*item_selection_ptr->cp < INVEN_PACK)) || (item_selection_ptr->equip && (*item_selection_ptr->cp >= INVEN_RARM) && (*item_selection_ptr->cp < INVEN_TOTAL))) {
71 if (prev_tag && command_cmd) {
72 if (!get_tag(owner_ptr, &item_selection_ptr->k, prev_tag, (*item_selection_ptr->cp >= INVEN_RARM) ? USE_EQUIP : USE_INVEN, item_selection_ptr->tval)) /* Reject */
74 else if ((item_selection_ptr->k < INVEN_RARM) ? !item_selection_ptr->inven : !item_selection_ptr->equip) /* Reject */
76 else if (!get_item_okay(owner_ptr, item_selection_ptr->k, item_selection_ptr->tval)) /* Reject */
79 *item_selection_ptr->cp = item_selection_ptr->k;
80 item_selection_ptr->tval = 0;
81 item_tester_hook = NULL;
87 } else if (get_item_okay(owner_ptr, *item_selection_ptr->cp, item_selection_ptr->tval)) {
88 item_selection_ptr->tval = 0;
89 item_tester_hook = NULL;
97 item_selection_ptr->done = FALSE;
98 item_selection_ptr->item = FALSE;
99 item_selection_ptr->i1 = 0;
100 item_selection_ptr->i2 = INVEN_PACK - 1;
101 if (!item_selection_ptr->inven)
102 item_selection_ptr->i2 = -1;
104 for (int j = 0; j < INVEN_PACK; j++)
105 if (item_tester_okay(owner_ptr, &owner_ptr->inventory_list[j], item_selection_ptr->tval) || (item_selection_ptr->mode & USE_FULL))
106 item_selection_ptr->max_inven++;
108 while ((item_selection_ptr->i1 <= item_selection_ptr->i2) && (!get_item_okay(owner_ptr, item_selection_ptr->i1, item_selection_ptr->tval)))
109 item_selection_ptr->i1++;
111 while ((item_selection_ptr->i1 <= item_selection_ptr->i2) && (!get_item_okay(owner_ptr, item_selection_ptr->i2, item_selection_ptr->tval)))
112 item_selection_ptr->i2--;
114 item_selection_ptr->e1 = INVEN_RARM;
115 item_selection_ptr->e2 = INVEN_TOTAL - 1;
116 if (!item_selection_ptr->equip)
117 item_selection_ptr->e2 = -1;
119 for (int j = INVEN_RARM; j < INVEN_TOTAL; j++)
120 if (select_ring_slot ? is_ring_slot(j) : item_tester_okay(owner_ptr, &owner_ptr->inventory_list[j], item_selection_ptr->tval) || (item_selection_ptr->mode & USE_FULL))
121 item_selection_ptr->max_equip++;
123 if (owner_ptr->ryoute && !(item_selection_ptr->mode & IGNORE_BOTHHAND_SLOT))
124 item_selection_ptr->max_equip++;
127 while ((item_selection_ptr->e1 <= item_selection_ptr->e2) && (!get_item_okay(owner_ptr, item_selection_ptr->e1, item_selection_ptr->tval)))
128 item_selection_ptr->e1++;
130 while ((item_selection_ptr->e1 <= item_selection_ptr->e2) && (!get_item_okay(owner_ptr, item_selection_ptr->e2, item_selection_ptr->tval)))
131 item_selection_ptr->e2--;
133 if (item_selection_ptr->equip && owner_ptr->ryoute && !(item_selection_ptr->mode & IGNORE_BOTHHAND_SLOT)) {
134 if (owner_ptr->migite) {
135 if (item_selection_ptr->e2 < INVEN_LARM)
136 item_selection_ptr->e2 = INVEN_LARM;
137 } else if (owner_ptr->hidarite)
138 item_selection_ptr->e1 = INVEN_RARM;
141 if (item_selection_ptr->floor) {
142 for (item_selection_ptr->this_o_idx = owner_ptr->current_floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx; item_selection_ptr->this_o_idx; item_selection_ptr->this_o_idx = item_selection_ptr->next_o_idx) {
144 o_ptr = &owner_ptr->current_floor_ptr->o_list[item_selection_ptr->this_o_idx];
145 item_selection_ptr->next_o_idx = o_ptr->next_o_idx;
146 if ((item_tester_okay(owner_ptr, o_ptr, item_selection_ptr->tval) || (item_selection_ptr->mode & USE_FULL)) && (o_ptr->marked & OM_FOUND))
147 item_selection_ptr->allow_floor = TRUE;
151 if (!item_selection_ptr->allow_floor && (item_selection_ptr->i1 > item_selection_ptr->i2) && (item_selection_ptr->e1 > item_selection_ptr->e2)) {
153 item_selection_ptr->oops = TRUE;
154 item_selection_ptr->done = TRUE;
156 if (item_selection_ptr->mode & USE_FORCE) {
157 *item_selection_ptr->cp = INVEN_FORCE;
158 item_selection_ptr->item = TRUE;
161 if (command_see && command_wrk && item_selection_ptr->equip)
163 else if (item_selection_ptr->inven)
165 else if (item_selection_ptr->equip)
171 /* 追加オプション(always_show_list)が設定されている場合は常に一覧を表示する */
172 if ((always_show_list == TRUE) || use_menu)
178 while (!item_selection_ptr->done) {
179 COMMAND_CODE get_item_label = 0;
182 for (int j = 0; j < 8; j++) {
183 if (!angband_term[j])
186 if (window_flag[j] & (PW_INVEN))
189 if (window_flag[j] & (PW_EQUIP))
193 if ((command_wrk && ni && !ne) || (!command_wrk && !ni && ne)) {
194 toggle_inventory_equipment(owner_ptr);
195 item_selection_ptr->toggle = !item_selection_ptr->toggle;
198 owner_ptr->window |= (PW_INVEN | PW_EQUIP);
199 handle_stuff(owner_ptr);
203 get_item_label = show_inventory(owner_ptr, item_selection_ptr->menu_line, item_selection_ptr->mode, item_selection_ptr->tval);
206 get_item_label = show_equipment(owner_ptr, item_selection_ptr->menu_line, item_selection_ptr->mode, item_selection_ptr->tval);
210 sprintf(item_selection_ptr->out_val, _("持ち物:", "Inven:"));
211 if ((item_selection_ptr->i1 <= item_selection_ptr->i2) && !use_menu) {
212 sprintf(item_selection_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(item_selection_ptr->i1), index_to_label(item_selection_ptr->i2));
213 strcat(item_selection_ptr->out_val, item_selection_ptr->tmp_val);
216 if (!command_see && !use_menu)
217 strcat(item_selection_ptr->out_val, _(" '*'一覧,", " * to see,"));
219 if (item_selection_ptr->equip)
220 strcat(item_selection_ptr->out_val, format(_(" %s 装備品,", " %s for Equip,"), use_menu ? _("'4'or'6'", "4 or 6") : _("'/'", "/")));
222 sprintf(item_selection_ptr->out_val, _("装備品:", "Equip:"));
223 if ((item_selection_ptr->e1 <= item_selection_ptr->e2) && !use_menu) {
224 sprintf(item_selection_ptr->tmp_val, _("%c-%c,'(',')',", " %c-%c,'(',')',"), index_to_label(item_selection_ptr->e1), index_to_label(item_selection_ptr->e2));
225 strcat(item_selection_ptr->out_val, item_selection_ptr->tmp_val);
228 if (!command_see && !use_menu)
229 strcat(item_selection_ptr->out_val, _(" '*'一覧,", " * to see,"));
231 if (item_selection_ptr->inven)
232 strcat(item_selection_ptr->out_val, format(_(" %s 持ち物,", " %s for Inven,"), use_menu ? _("'4'or'6'", "4 or 6") : _("'/'", "'/'")));
235 if (item_selection_ptr->allow_floor)
236 strcat(item_selection_ptr->out_val, _(" '-'床上,", " - for item_selection_ptr->floor,"));
238 if (item_selection_ptr->mode & USE_FORCE)
239 strcat(item_selection_ptr->out_val, _(" 'w'練気術,", " w for the Force,"));
241 strcat(item_selection_ptr->out_val, " ESC");
242 sprintf(item_selection_ptr->tmp_val, "(%s) %s", item_selection_ptr->out_val, pmt);
243 prt(item_selection_ptr->tmp_val, 0, 0);
244 item_selection_ptr->which = inkey();
246 int max_line = (command_wrk ? item_selection_ptr->max_equip : item_selection_ptr->max_inven);
247 switch (item_selection_ptr->which) {
252 item_selection_ptr->done = TRUE;
259 item_selection_ptr->menu_line += (max_line - 1);
266 item_selection_ptr->menu_line++;
276 if (!item_selection_ptr->inven || !item_selection_ptr->equip) {
286 command_wrk = !command_wrk;
287 max_line = (command_wrk ? item_selection_ptr->max_equip : item_selection_ptr->max_inven);
288 if (item_selection_ptr->menu_line > max_line)
289 item_selection_ptr->menu_line = max_line;
298 if (command_wrk == USE_FLOOR) {
299 *item_selection_ptr->cp = -get_item_label;
301 if (!get_item_okay(owner_ptr, get_item_label, item_selection_ptr->tval)) {
306 if (!get_item_allow(owner_ptr, get_item_label)) {
307 item_selection_ptr->done = TRUE;
311 *item_selection_ptr->cp = get_item_label;
314 item_selection_ptr->item = TRUE;
315 item_selection_ptr->done = TRUE;
319 if (item_selection_ptr->mode & USE_FORCE) {
320 *item_selection_ptr->cp = INVEN_FORCE;
321 item_selection_ptr->item = TRUE;
322 item_selection_ptr->done = TRUE;
328 if (item_selection_ptr->menu_line > max_line)
329 item_selection_ptr->menu_line -= max_line;
334 switch (item_selection_ptr->which) {
336 item_selection_ptr->done = TRUE;
353 if (!item_selection_ptr->inven || !item_selection_ptr->equip) {
363 command_wrk = !command_wrk;
367 if (item_selection_ptr->allow_floor) {
368 for (item_selection_ptr->this_o_idx = owner_ptr->current_floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx; item_selection_ptr->this_o_idx; item_selection_ptr->this_o_idx = item_selection_ptr->next_o_idx) {
370 o_ptr = &owner_ptr->current_floor_ptr->o_list[item_selection_ptr->this_o_idx];
371 item_selection_ptr->next_o_idx = o_ptr->next_o_idx;
372 if (!item_tester_okay(owner_ptr, o_ptr, item_selection_ptr->tval) && !(item_selection_ptr->mode & USE_FULL))
375 item_selection_ptr->k = 0 - item_selection_ptr->this_o_idx;
376 if (other_query_flag && !verify(owner_ptr, _("本当に", "Try"), item_selection_ptr->k) || !get_item_allow(owner_ptr, item_selection_ptr->k))
379 *item_selection_ptr->cp = item_selection_ptr->k;
380 item_selection_ptr->item = TRUE;
381 item_selection_ptr->done = TRUE;
385 if (item_selection_ptr->done)
402 if (!get_tag(owner_ptr, &item_selection_ptr->k, item_selection_ptr->which, command_wrk ? USE_EQUIP : USE_INVEN, item_selection_ptr->tval)) {
407 if ((item_selection_ptr->k < INVEN_RARM) ? !item_selection_ptr->inven : !item_selection_ptr->equip) {
412 if (!get_item_okay(owner_ptr, item_selection_ptr->k, item_selection_ptr->tval)) {
417 if (!get_item_allow(owner_ptr, item_selection_ptr->k)) {
418 item_selection_ptr->done = TRUE;
422 *item_selection_ptr->cp = item_selection_ptr->k;
423 item_selection_ptr->item = TRUE;
424 item_selection_ptr->done = TRUE;
425 item_selection_ptr->cur_tag = item_selection_ptr->which;
429 if (item_selection_ptr->mode & USE_FORCE) {
430 *item_selection_ptr->cp = INVEN_FORCE;
431 item_selection_ptr->item = TRUE;
432 item_selection_ptr->done = TRUE;
439 bool not_found = FALSE;
440 if (!get_tag(owner_ptr, &item_selection_ptr->k, item_selection_ptr->which, command_wrk ? USE_EQUIP : USE_INVEN, item_selection_ptr->tval)) {
442 } else if ((item_selection_ptr->k < INVEN_RARM) ? !item_selection_ptr->inven : !item_selection_ptr->equip) {
444 } else if (!get_item_okay(owner_ptr, item_selection_ptr->k, item_selection_ptr->tval)) {
449 *item_selection_ptr->cp = item_selection_ptr->k;
450 item_selection_ptr->item = TRUE;
451 item_selection_ptr->done = TRUE;
452 item_selection_ptr->cur_tag = item_selection_ptr->which;
456 ver = isupper(item_selection_ptr->which);
457 item_selection_ptr->which = (char)tolower(item_selection_ptr->which);
459 if (item_selection_ptr->which == '(')
460 item_selection_ptr->k = item_selection_ptr->i1;
461 else if (item_selection_ptr->which == ')')
462 item_selection_ptr->k = item_selection_ptr->i2;
464 item_selection_ptr->k = label_to_inventory(owner_ptr, item_selection_ptr->which);
466 if (item_selection_ptr->which == '(')
467 item_selection_ptr->k = item_selection_ptr->e1;
468 else if (item_selection_ptr->which == ')')
469 item_selection_ptr->k = item_selection_ptr->e2;
471 item_selection_ptr->k = label_to_equipment(owner_ptr, item_selection_ptr->which);
474 if (!get_item_okay(owner_ptr, item_selection_ptr->k, item_selection_ptr->tval)) {
479 if (ver && !verify(owner_ptr, _("本当に", "Try"), item_selection_ptr->k)) {
480 item_selection_ptr->done = TRUE;
484 if (!get_item_allow(owner_ptr, item_selection_ptr->k)) {
485 item_selection_ptr->done = TRUE;
489 *item_selection_ptr->cp = item_selection_ptr->k;
490 item_selection_ptr->item = TRUE;
491 item_selection_ptr->done = TRUE;
502 item_selection_ptr->tval = 0;
503 item_tester_hook = NULL;
504 if (item_selection_ptr->toggle)
505 toggle_inventory_equipment(owner_ptr);
507 owner_ptr->window |= (PW_INVEN | PW_EQUIP);
508 handle_stuff(owner_ptr);
510 if (item_selection_ptr->oops && str)
513 if (item_selection_ptr->item) {
514 repeat_push(*item_selection_ptr->cp);
516 prev_tag = item_selection_ptr->cur_tag;
520 return item_selection_ptr->item;