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"
22 * @brief プレイヤーの所持/装備オブジェクトIDが指輪枠かを返す /
23 * @param i プレイヤーの所持/装備オブジェクトID
24 * @return 指輪枠ならばTRUEを返す。
26 bool is_ring_slot(int i) { return (i == INVEN_MAIN_RING) || (i == INVEN_SUB_RING); }
29 * @brief 床オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
30 * Find the "first" inventory object with the given "tag".
31 * @param cp 対応するタグIDを与える参照ポインタ
32 * @param tag 該当するオブジェクトがあるかを調べたいタグ
33 * @param floor_list 床上アイテムの配列
34 * @param floor_num 床上アイテムの配列ID
35 * @return タグに該当するオブジェクトがあるならTRUEを返す
37 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
38 * inscription of an object. Alphabetical characters don't work as a\n
41 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
42 * and "x" is the "current" command_cmd code.\n
44 bool get_tag_floor(floor_type *floor_ptr, COMMAND_CODE *cp, char tag, FLOOR_IDX floor_list[], ITEM_NUMBER floor_num)
46 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
47 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
48 if (!o_ptr->inscription)
51 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
53 if ((s[1] == command_cmd) && (s[2] == tag)) {
58 s = angband_strchr(s + 1, '@');
62 if (tag < '0' || '9' < tag) {
66 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
67 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
68 if (!o_ptr->inscription)
71 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
78 s = angband_strchr(s + 1, '@');
86 * @brief 所持/装備オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
87 * Find the "first" inventory object with the given "tag".
88 * @param owner_ptr プレーヤーへの参照ポインタ
89 * @param cp 対応するタグIDを与える参照ポインタ
90 * @param tag 該当するオブジェクトがあるかを調べたいタグ
91 * @param mode 所持、装備の切り替え
92 * @return タグに該当するオブジェクトがあるならTRUEを返す
94 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
95 * inscription of an object. Alphabetical characters don't work as a\n
98 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
99 * and "x" is the "current" command_cmd code.\n
101 bool get_tag(player_type *owner_ptr, COMMAND_CODE *cp, char tag, BIT_FLAGS mode, tval_type tval)
103 COMMAND_CODE start, end;
106 start = INVEN_MAIN_HAND;
107 end = INVEN_TOTAL - 1;
112 end = INVEN_PACK - 1;
119 for (COMMAND_CODE i = start; i <= end; i++) {
120 object_type *o_ptr = &owner_ptr->inventory_list[i];
121 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
124 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
127 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
129 if ((s[1] == command_cmd) && (s[2] == tag)) {
134 s = angband_strchr(s + 1, '@');
138 if (tag < '0' || '9' < tag)
141 for (COMMAND_CODE i = start; i <= end; i++) {
142 object_type *o_ptr = &owner_ptr->inventory_list[i];
143 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
146 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
149 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
156 s = angband_strchr(s + 1, '@');
164 * @brief プレイヤーの所持/装備オブジェクトが正規のものかを返す /
165 * Auxiliary function for "get_item()" -- test an index
167 * @return 正規のIDならばTRUEを返す。
169 bool get_item_okay(player_type *owner_ptr, OBJECT_IDX i, tval_type item_tester_tval)
171 if ((i < 0) || (i >= INVEN_TOTAL))
174 if (owner_ptr->select_ring_slot)
175 return is_ring_slot(i);
177 return item_tester_okay(owner_ptr, &owner_ptr->inventory_list[i], item_tester_tval);
181 * @brief 選択したアイテムの確認処理のメインルーチン /
182 * @param owner_ptr プレーヤーへの参照ポインタ
183 * @param item 選択アイテムID
184 * @return 確認がYesならTRUEを返す。
185 * @details The item can be negative to mean "item on floor".
186 * Hack -- allow user to "prevent" certain choices
188 bool get_item_allow(player_type *owner_ptr, INVENTORY_IDX item)
195 o_ptr = &owner_ptr->inventory_list[item];
197 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
199 if (!o_ptr->inscription)
202 concptr s = angband_strchr(quark_str(o_ptr->inscription), '!');
204 if ((s[1] == command_cmd) || (s[1] == '*'))
205 if (!verify(owner_ptr, _("本当に", "Really try"), item))
208 s = angband_strchr(s + 1, '!');
215 * @brief 選択アルファベットラベルからプレイヤーの装備オブジェクトIDを返す /
216 * @param owner_ptr プレーヤーへの参照ポインタ
217 * Convert a label into the index of a item in the "equip"
218 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
220 INVENTORY_IDX label_to_equipment(player_type *owner_ptr, int c)
222 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1) + INVEN_MAIN_HAND;
224 if ((i < INVEN_MAIN_HAND) || (i >= INVEN_TOTAL))
227 if (owner_ptr->select_ring_slot)
228 return is_ring_slot(i) ? i : -1;
230 if (!owner_ptr->inventory_list[i].k_idx)
237 * @brief 選択アルファベットラベルからプレイヤーの所持オブジェクトIDを返す /
238 * Convert a label into the index of an item in the "inven"
239 * @param owner_ptr プレーヤーへの参照ポインタ
240 * @param c 選択されたアルファベット
241 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
242 * @details Note that the label does NOT distinguish inven/equip.
244 INVENTORY_IDX label_to_inventory(player_type *owner_ptr, int c)
246 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1);
248 if ((i < 0) || (i > INVEN_PACK) || (owner_ptr->inventory_list[i].k_idx == 0))
255 * @brief 選択したアイテムの確認処理の補助 /
256 * Verify the choice of an item.
257 * @param owner_ptr プレーヤーへの参照ポインタ
258 * @param prompt メッセージ表示の一部
259 * @param item 選択アイテムID
260 * @return 確認がYesならTRUEを返す。
261 * @details The item can be negative to mean "item on floor".
263 bool verify(player_type *owner_ptr, concptr prompt, INVENTORY_IDX item)
265 GAME_TEXT o_name[MAX_NLEN];
266 char out_val[MAX_NLEN + 20];
269 o_ptr = &owner_ptr->inventory_list[item];
271 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
273 describe_flavor(owner_ptr, o_name, o_ptr, 0);
274 (void)sprintf(out_val, _("%s%sですか? ", "%s %s? "), prompt, o_name);
275 return get_check(out_val);
279 * @brief タグIDにあわせてタグアルファベットのリストを返す /
280 * Move around label characters with correspond tags
281 * @param owner_ptr プレーヤーへの参照ポインタ
282 * @param label ラベルリストを取得する文字列参照ポインタ
283 * @param mode 所持品リストか装備品リストかの切り替え
286 void prepare_label_string(player_type *owner_ptr, char *label, BIT_FLAGS mode, tval_type tval)
288 concptr alphabet_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
289 int offset = (mode == USE_EQUIP) ? INVEN_MAIN_HAND : 0;
290 strcpy(label, alphabet_chars);
291 for (int i = 0; i < 52; i++) {
293 SYMBOL_CODE c = alphabet_chars[i];
294 if (!get_tag(owner_ptr, &index, c, mode, tval))
300 label[index - offset] = c;