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 "system/player-type-definition.h"
18 #include "util/int-char-converter.h"
19 #include "util/quarks.h"
20 #include "util/string-processor.h"
23 * @brief プレイヤーの所持/装備オブジェクトIDが指輪枠かを返す /
24 * @param i プレイヤーの所持/装備オブジェクトID
25 * @return 指輪枠ならばTRUEを返す。
27 bool is_ring_slot(int i) { return (i == INVEN_MAIN_RING) || (i == INVEN_SUB_RING); }
30 * @brief 床オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
31 * Find the "first" inventory object with the given "tag".
32 * @param cp 対応するタグIDを与える参照ポインタ
33 * @param tag 該当するオブジェクトがあるかを調べたいタグ
34 * @param floor_list 床上アイテムの配列
35 * @param floor_num 床上アイテムの配列ID
36 * @return タグに該当するオブジェクトがあるならTRUEを返す
38 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
39 * inscription of an object. Alphabetical characters don't work as a\n
42 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
43 * and "x" is the "current" command_cmd code.\n
45 bool get_tag_floor(floor_type *floor_ptr, COMMAND_CODE *cp, char tag, FLOOR_IDX floor_list[], ITEM_NUMBER floor_num)
47 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
48 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
49 if (!o_ptr->inscription)
52 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
54 if ((s[1] == command_cmd) && (s[2] == tag)) {
59 s = angband_strchr(s + 1, '@');
63 if (tag < '0' || '9' < tag) {
67 for (COMMAND_CODE i = 0; i < floor_num && i < 23; i++) {
68 object_type *o_ptr = &floor_ptr->o_list[floor_list[i]];
69 if (!o_ptr->inscription)
72 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
79 s = angband_strchr(s + 1, '@');
87 * @brief 所持/装備オブジェクトに選択タグを与える/タグに該当するオブジェクトがあるかを返す /
88 * Find the "first" inventory object with the given "tag".
89 * @param owner_ptr プレーヤーへの参照ポインタ
90 * @param cp 対応するタグIDを与える参照ポインタ
91 * @param tag 該当するオブジェクトがあるかを調べたいタグ
92 * @param mode 所持、装備の切り替え
93 * @return タグに該当するオブジェクトがあるならTRUEを返す
95 * A "tag" is a numeral "n" appearing as "@n" anywhere in the\n
96 * inscription of an object. Alphabetical characters don't work as a\n
99 * Also, the tag "@xn" will work as well, where "n" is a any tag-char,\n
100 * and "x" is the "current" command_cmd code.\n
102 bool get_tag(player_type *owner_ptr, COMMAND_CODE *cp, char tag, BIT_FLAGS mode, tval_type tval)
104 COMMAND_CODE start, end;
107 start = INVEN_MAIN_HAND;
108 end = INVEN_TOTAL - 1;
113 end = INVEN_PACK - 1;
120 for (COMMAND_CODE i = start; i <= end; i++) {
121 object_type *o_ptr = &owner_ptr->inventory_list[i];
122 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
125 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
128 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
130 if ((s[1] == command_cmd) && (s[2] == tag)) {
135 s = angband_strchr(s + 1, '@');
139 if (tag < '0' || '9' < tag)
142 for (COMMAND_CODE i = start; i <= end; i++) {
143 object_type *o_ptr = &owner_ptr->inventory_list[i];
144 if ((o_ptr->k_idx == 0) || (o_ptr->inscription == 0))
147 if (!item_tester_okay(owner_ptr, o_ptr, tval) && !(mode & USE_FULL))
150 concptr s = angband_strchr(quark_str(o_ptr->inscription), '@');
157 s = angband_strchr(s + 1, '@');
165 * @brief プレイヤーの所持/装備オブジェクトが正規のものかを返す /
166 * Auxiliary function for "get_item()" -- test an index
168 * @return 正規のIDならばTRUEを返す。
170 bool get_item_okay(player_type *owner_ptr, OBJECT_IDX i, tval_type item_tester_tval)
172 if ((i < 0) || (i >= INVEN_TOTAL))
175 if (owner_ptr->select_ring_slot)
176 return is_ring_slot(i);
178 return item_tester_okay(owner_ptr, &owner_ptr->inventory_list[i], item_tester_tval);
182 * @brief 選択したアイテムの確認処理のメインルーチン /
183 * @param owner_ptr プレーヤーへの参照ポインタ
184 * @param item 選択アイテムID
185 * @return 確認がYesならTRUEを返す。
186 * @details The item can be negative to mean "item on floor".
187 * Hack -- allow user to "prevent" certain choices
189 bool get_item_allow(player_type *owner_ptr, INVENTORY_IDX item)
196 o_ptr = &owner_ptr->inventory_list[item];
198 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
200 if (!o_ptr->inscription)
203 concptr s = angband_strchr(quark_str(o_ptr->inscription), '!');
205 if ((s[1] == command_cmd) || (s[1] == '*'))
206 if (!verify(owner_ptr, _("本当に", "Really try"), item))
209 s = angband_strchr(s + 1, '!');
216 * @brief 選択アルファベットラベルからプレイヤーの装備オブジェクトIDを返す /
217 * @param owner_ptr プレーヤーへの参照ポインタ
218 * Convert a label into the index of a item in the "equip"
219 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
221 INVENTORY_IDX label_to_equipment(player_type *owner_ptr, int c)
223 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1) + INVEN_MAIN_HAND;
225 if ((i < INVEN_MAIN_HAND) || (i >= INVEN_TOTAL))
228 if (owner_ptr->select_ring_slot)
229 return is_ring_slot(i) ? i : -1;
231 if (!owner_ptr->inventory_list[i].k_idx)
238 * @brief 選択アルファベットラベルからプレイヤーの所持オブジェクトIDを返す /
239 * Convert a label into the index of an item in the "inven"
240 * @param owner_ptr プレーヤーへの参照ポインタ
241 * @param c 選択されたアルファベット
242 * @return 対応するID。該当スロットにオブジェクトが存在しなかった場合-1を返す / Return "-1" if the label does not indicate a real item
243 * @details Note that the label does NOT distinguish inven/equip.
245 INVENTORY_IDX label_to_inventory(player_type *owner_ptr, int c)
247 INVENTORY_IDX i = (INVENTORY_IDX)(islower(c) ? A2I(c) : -1);
249 if ((i < 0) || (i > INVEN_PACK) || (owner_ptr->inventory_list[i].k_idx == 0))
256 * @brief 選択したアイテムの確認処理の補助 /
257 * Verify the choice of an item.
258 * @param owner_ptr プレーヤーへの参照ポインタ
259 * @param prompt メッセージ表示の一部
260 * @param item 選択アイテムID
261 * @return 確認がYesならTRUEを返す。
262 * @details The item can be negative to mean "item on floor".
264 bool verify(player_type *owner_ptr, concptr prompt, INVENTORY_IDX item)
266 GAME_TEXT o_name[MAX_NLEN];
267 char out_val[MAX_NLEN + 20];
270 o_ptr = &owner_ptr->inventory_list[item];
272 o_ptr = &owner_ptr->current_floor_ptr->o_list[0 - item];
274 describe_flavor(owner_ptr, o_name, o_ptr, 0);
275 (void)sprintf(out_val, _("%s%sですか? ", "%s %s? "), prompt, o_name);
276 return get_check(out_val);
280 * @brief タグIDにあわせてタグアルファベットのリストを返す /
281 * Move around label characters with correspond tags
282 * @param owner_ptr プレーヤーへの参照ポインタ
283 * @param label ラベルリストを取得する文字列参照ポインタ
284 * @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;