2 * @brief インベントリ関係のユーティリティ
5 * @details 少々雑多なので後で整理を検討する
8 #include "inventory/inventory-util.h"
9 #include "core/asking-player.h"
10 #include "flavor/flavor-describer.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "io/input-key-requester.h"
13 #include "object/item-tester-hooker.h"
14 #include "object/item-use-flags.h"
15 #include "system/floor-type-definition.h"
16 #include "system/object-type-definition.h"
17 #include "util/int-char-converter.h"
18 #include "util/quarks.h"
19 #include "util/string-processor.h"
21 bool select_ring_slot;
24 * @brief プレイヤーの所持/装備オブジェクトIDが指輪枠かを返す /
25 * @param i プレイヤーの所持/装備オブジェクトID
26 * @return 指輪枠ならばTRUEを返す。
28 bool is_ring_slot(int i) { return (i == INVEN_RIGHT) || (i == INVEN_LEFT); }
31 * @brief 床オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
32 * Find the "first" inventory object with the given "tag".
33 * @param cp 対応するタグIDを与える参照ポインタ
34 * @param tag 該当するオブジェクトがあるかを調べたいタグ
35 * @param floor_list 床上アイテムの配列
36 * @param floor_num 床上アイテムの配列ID
37 * @return タグに該当するオブジェクトがあるならTRUEを返す
39 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
40 * inscription of an object. Alphabetical characters don't work as a\n
43 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
44 * and "x" is the "current" command_cmd code.\n
46 bool get_tag_floor(floor_type *floor_ptr, COMMAND_CODE *cp, char tag, FLOOR_IDX floor_list[], ITEM_NUMBER floor_num)
48 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
49 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
50 if (!o_ptr->inscription)
53 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
55 if ((s[1] == command_cmd) && (s[2] == tag)) {
60 s = angband_strchr(s + 1, '@');
64 if (tag < '0' || '9' < tag) {
68 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
69 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
70 if (!o_ptr->inscription)
73 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
80 s = angband_strchr(s + 1, '@');
88 * @brief 所持/装備オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
89 * Find the "first" inventory object with the given "tag".
90 * @param owner_ptr プレーヤーへの参照ポインタ
91 * @param cp 対応するタグIDを与える参照ポインタ
92 * @param tag 該当するオブジェクトがあるかを調べたいタグ
93 * @param mode 所持、装備の切り替え
94 * @return タグに該当するオブジェクトがあるならTRUEを返す
96 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
97 * inscription of an object. Alphabetical characters don't work as a\n
100 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
101 * and "x" is the "current" command_cmd code.\n
103 bool get_tag(player_type *owner_ptr, COMMAND_CODE *cp, char tag, BIT_FLAGS mode, tval_type tval)
105 COMMAND_CODE start, end;
109 end = INVEN_TOTAL - 1;
114 end = INVEN_PACK - 1;
121 for (COMMAND_CODE i = start; i <= end; i++) {
122 object_type *o_ptr = &owner_ptr->inventory_list[i];
123 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
126 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
129 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
131 if ((s[1] == command_cmd) && (s[2] == tag)) {
136 s = angband_strchr(s + 1, '@');
140 if (tag < '0' || '9' < tag)
143 for (COMMAND_CODE i = start; i <= end; i++) {
144 object_type *o_ptr = &owner_ptr->inventory_list[i];
145 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
148 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
151 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
158 s = angband_strchr(s + 1, '@');
166 * @brief プレイヤーの所持/装備オブジェクトが正規のものかを返す /
167 * Auxiliary function for "get_item()" -- test an index
169 * @return 正規のIDならばTRUEを返す。
171 bool get_item_okay(player_type *owner_ptr, OBJECT_IDX i, tval_type item_tester_tval)
173 if ((i < 0) || (i >= INVEN_TOTAL))
176 if (select_ring_slot)
177 return is_ring_slot(i);
179 return item_tester_okay(owner_ptr, &owner_ptr->inventory_list[i], item_tester_tval);
183 * @brief 選択したアイテムの確認処理のメインルーチン /
184 * @param owner_ptr プレーヤーへの参照ポインタ
185 * @param item 選択アイテムID
186 * @return 確認がYesならTRUEを返す。
187 * @details The item can be negative to mean "item on floor".
188 * Hack -- allow user to "prevent" certain choices
190 bool get_item_allow(player_type *owner_ptr, INVENTORY_IDX item)
197 o_ptr = &owner_ptr->inventory_list[item];
199 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
201 if (!o_ptr->inscription)
204 concptr s = angband_strchr(quark_str(o_ptr->inscription), '!');
206 if ((s[1] == command_cmd) || (s[1] == '*'))
207 if (!verify(owner_ptr, _("本当に", "Really try"), item))
210 s = angband_strchr(s + 1, '!');
217 * @brief 選択アルファベットラベルからプレイヤーの装備オブジェクトIDを返す /
218 * @param owner_ptr プレーヤーへの参照ポインタ
219 * Convert a label into the index of a item in the "equip"
220 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
222 INVENTORY_IDX label_to_equipment(player_type *owner_ptr, int c)
224 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1) + INVEN_RARM;
226 if ((i < INVEN_RARM) || (i >= INVEN_TOTAL))
229 if (select_ring_slot)
230 return is_ring_slot(i) ? i : -1;
232 if (!owner_ptr->inventory_list[i].k_idx)
239 * @brief 選択アルファベットラベルからプレイヤーの所持オブジェクトIDを返す /
240 * Convert a label into the index of an item in the "inven"
241 * @param owner_ptr プレーヤーへの参照ポインタ
242 * @param c 選択されたアルファベット
243 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
244 * @details Note that the label does NOT distinguish inven/equip.
246 INVENTORY_IDX label_to_inventory(player_type *owner_ptr, int c)
248 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1);
250 if ((i < 0) || (i > INVEN_PACK) || (owner_ptr->inventory_list[i].k_idx == 0))
257 * @brief 選択したアイテムの確認処理の補助 /
258 * Verify the choice of an item.
259 * @param owner_ptr プレーヤーへの参照ポインタ
260 * @param prompt メッセージ表示の一部
261 * @param item 選択アイテムID
262 * @return 確認がYesならTRUEを返す。
263 * @details The item can be negative to mean "item on floor".
265 bool verify(player_type *owner_ptr, concptr prompt, INVENTORY_IDX item)
267 GAME_TEXT o_name[MAX_NLEN];
268 char out_val[MAX_NLEN + 20];
271 o_ptr = &owner_ptr->inventory_list[item];
273 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
275 describe_flavor(owner_ptr, o_name, o_ptr, 0);
276 (void)sprintf(out_val, _("%s%sですか? ", "%s %s? "), prompt, o_name);
277 return get_check(out_val);
281 * @brief タグIDにあわせてタグアルファベットのリストを返す /
282 * Move around label characters with correspond tags
283 * @param owner_ptr プレーヤーへの参照ポインタ
284 * @param label ラベルリストを取得する文字列参照ポインタ
285 * @param mode 所持品リストか装備品リストかの切り替え
288 void prepare_label_string(player_type *owner_ptr, char *label, BIT_FLAGS mode, tval_type tval)
290 concptr alphabet_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
291 int offset = (mode == USE_EQUIP) ? INVEN_RARM : 0;
292 strcpy(label, alphabet_chars);
293 for (int i = 0; i < 52; i++) {
295 SYMBOL_CODE c = alphabet_chars[i];
296 if (!get_tag(owner_ptr, &index, c, mode, tval))
302 label[index - offset] = c;