1 #include "inventory/inventory-object.h"
2 #include "object/object-flavor.h"
3 #include "object/object2.h" // 暫定、相互参照している.
4 #include "player/player-effects.h" // 暫定、相互参照している.
5 #include "view/object-describer.h"
7 void vary_item(player_type *owner_ptr, INVENTORY_IDX item, ITEM_NUMBER num)
10 inven_item_increase(owner_ptr, item, num);
11 inven_item_describe(owner_ptr, item);
12 inven_item_optimize(owner_ptr, item);
16 floor_type *floor_ptr = owner_ptr->current_floor_ptr;
17 floor_item_increase(floor_ptr, 0 - item, num);
18 floor_item_describe(owner_ptr, 0 - item);
19 floor_item_optimize(owner_ptr, 0 - item);
23 * @brief アイテムを増減させ残り所持数メッセージを表示する /
24 * Increase the "number" of an item in the inventory
25 * @param owner_ptr プレーヤーへの参照ポインタ
26 * @param item 所持数を増やしたいプレイヤーのアイテム所持スロット
30 void inven_item_increase(player_type *owner_ptr, INVENTORY_IDX item, ITEM_NUMBER num)
32 object_type *o_ptr = &owner_ptr->inventory_list[item];
44 owner_ptr->total_weight += (num * o_ptr->weight);
45 owner_ptr->update |= (PU_BONUS);
46 owner_ptr->update |= (PU_MANA);
47 owner_ptr->update |= (PU_COMBINE);
48 owner_ptr->window |= (PW_INVEN | PW_EQUIP);
50 if (o_ptr->number || !owner_ptr->ele_attack)
52 if (!(item == INVEN_RARM) && !(item == INVEN_LARM))
54 if (has_melee_weapon(owner_ptr, INVEN_RARM + INVEN_LARM - item))
57 set_ele_attack(owner_ptr, 0, 0);
61 * @brief 所持アイテムスロットから所持数のなくなったアイテムを消去する /
62 * Erase an inventory slot if it has no more items
63 * @param owner_ptr プレーヤーへの参照ポインタ
64 * @param item 消去したいプレイヤーのアイテム所持スロット
67 void inven_item_optimize(player_type *owner_ptr, INVENTORY_IDX item)
69 object_type *o_ptr = &owner_ptr->inventory_list[item];
75 if (item >= INVEN_RARM) {
76 owner_ptr->equip_cnt--;
77 object_wipe(&owner_ptr->inventory_list[item]);
78 owner_ptr->update |= PU_BONUS;
79 owner_ptr->update |= PU_TORCH;
80 owner_ptr->update |= PU_MANA;
82 owner_ptr->window |= PW_EQUIP;
83 owner_ptr->window |= PW_SPELL;
87 owner_ptr->inven_cnt--;
89 for (i = item; i < INVEN_PACK; i++) {
90 owner_ptr->inventory_list[i] = owner_ptr->inventory_list[i + 1];
93 object_wipe(&owner_ptr->inventory_list[i]);
94 owner_ptr->window |= PW_INVEN;
95 owner_ptr->window |= PW_SPELL;
99 * @brief 所持スロットから床下にオブジェクトを落とすメインルーチン /
100 * Drop (some of) a non-cursed inventory/equipment item
101 * @param owner_ptr プレーヤーへの参照ポインタ
102 * @param item 所持テーブルのID
106 * The object will be dropped "near" the current location
108 void drop_from_inventory(player_type *owner_ptr, INVENTORY_IDX item, ITEM_NUMBER amt)
113 GAME_TEXT o_name[MAX_NLEN];
114 o_ptr = &owner_ptr->inventory_list[item];
118 if (amt > o_ptr->number)
121 if (item >= INVEN_RARM) {
122 item = inven_takeoff(owner_ptr, item, amt);
123 o_ptr = &owner_ptr->inventory_list[item];
127 object_copy(q_ptr, o_ptr);
128 distribute_charges(o_ptr, q_ptr, amt);
131 object_desc(owner_ptr, o_name, q_ptr, 0);
132 msg_format(_("%s(%c)を落とした。", "You drop %s (%c)."), o_name, index_to_label(item));
133 (void)drop_near(owner_ptr, q_ptr, 0, owner_ptr->y, owner_ptr->x);
134 vary_item(owner_ptr, item, -amt);
138 * @brief プレイヤーの所持スロットに存在するオブジェクトをまとめなおす /
139 * Combine items in the pack
142 * Note special handling of the "overflow" slot
144 void combine_pack(player_type *owner_ptr)
147 bool is_first_combination = TRUE;
148 bool combined = TRUE;
149 while (is_first_combination || combined) {
150 is_first_combination = FALSE;
153 for (int i = INVEN_PACK; i > 0; i--) {
155 o_ptr = &owner_ptr->inventory_list[i];
158 for (int j = 0; j < i; j++) {
160 j_ptr = &owner_ptr->inventory_list[j];
165 * Get maximum number of the stack if these
166 * are similar, get zero otherwise.
168 int max_num = object_similar_part(j_ptr, o_ptr);
170 bool is_max = (max_num != 0) && (j_ptr->number < max_num);
174 if (o_ptr->number + j_ptr->number <= max_num) {
176 object_absorb(j_ptr, o_ptr);
177 owner_ptr->inven_cnt--;
179 for (k = i; k < INVEN_PACK; k++) {
180 owner_ptr->inventory_list[k] = owner_ptr->inventory_list[k + 1];
183 object_wipe(&owner_ptr->inventory_list[k]);
185 int old_num = o_ptr->number;
186 int remain = j_ptr->number + o_ptr->number - max_num;
187 object_absorb(j_ptr, o_ptr);
188 o_ptr->number = remain;
189 if (o_ptr->tval == TV_ROD) {
190 o_ptr->pval = o_ptr->pval * remain / old_num;
191 o_ptr->timeout = o_ptr->timeout * remain / old_num;
194 if (o_ptr->tval == TV_WAND) {
195 o_ptr->pval = o_ptr->pval * remain / old_num;
199 owner_ptr->window |= (PW_INVEN);
207 msg_print(_("ザックの中のアイテムをまとめ直した。", "You combine some items in your pack."));
211 * @brief プレイヤーの所持スロットに存在するオブジェクトを並び替える /
212 * Reorder items in the pack
213 * @param owner_ptr プレーヤーへの参照ポインタ
216 * Note special handling of the "overflow" slot
218 void reorder_pack(player_type *owner_ptr)
227 for (i = 0; i < INVEN_PACK; i++) {
228 if ((i == INVEN_PACK) && (owner_ptr->inven_cnt == INVEN_PACK))
231 o_ptr = &owner_ptr->inventory_list[i];
235 o_value = object_value(o_ptr);
236 for (j = 0; j < INVEN_PACK; j++) {
237 if (object_sort_comp(o_ptr, o_value, &owner_ptr->inventory_list[j]))
246 object_copy(q_ptr, &owner_ptr->inventory_list[i]);
247 for (k = i; k > j; k--) {
248 object_copy(&owner_ptr->inventory_list[k], &owner_ptr->inventory_list[k - 1]);
251 object_copy(&owner_ptr->inventory_list[j], q_ptr);
252 owner_ptr->window |= (PW_INVEN);
256 msg_print(_("ザックの中のアイテムを並べ直した。", "You reorder some items in your pack."));