OSDN Git Service

[Refactor] #40498 Separated player-update-types.h from player-status.h
[hengband/hengband.git] / src / market / building-recharger.c
1 #include "market/building-recharger.h"
2 #include "autopick/autopick.h"
3 #include "core/asking-player.h"
4 #include "core/player-update-types.h"
5 #include "floor/floor-object.h"
6 #include "inventory/inventory-slot-types.h"
7 #include "market/building-util.h"
8 #include "object-enchant/special-object-flags.h"
9 #include "object-hook/hook-magic.h"
10 #include "object/item-use-flags.h"
11 #include "object/object-flavor.h"
12 #include "object/item-tester-hooker.h"
13 #include "object/object-kind.h"
14 #include "perception/object-perception.h"
15 #include "spell-kind/spells-perception.h"
16 #include "term/screen-processor.h"
17 #include "view/display-messages.h"
18
19 /*!
20  * @brief 魔道具の使用回数を回復させる施設のメインルーチン / Recharge rods, wands and staffs
21  * @details
22  * The player can select the number of charges to add\n
23  * (up to a limit), and the recharge never fails.\n
24  *\n
25  * The cost for rods depends on the level of the rod. The prices\n
26  * for recharging wands and staffs are dependent on the cost of\n
27  * the base-item.\n
28  * @param player_ptr プレーヤーへの参照ポインタ
29  * @return なし
30  */
31 void building_recharge(player_type *player_ptr)
32 {
33     msg_flag = FALSE;
34     clear_bldg(4, 18);
35     prt(_("  再充填の費用はアイテムの種類によります。", "  The prices of recharge depend on the type."), 6, 0);
36     item_tester_hook = item_tester_hook_recharge;
37
38     concptr q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
39     concptr s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
40
41     OBJECT_IDX item;
42     object_type *o_ptr;
43     o_ptr = choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
44     if (!o_ptr)
45         return;
46
47     object_kind *k_ptr;
48     k_ptr = &k_info[o_ptr->k_idx];
49
50     /*
51      * We don't want to give the player free info about
52      * the level of the item or the number of charges.
53      */
54     /* The item must be "known" */
55     char tmp_str[MAX_NLEN];
56     if (!object_is_known(o_ptr)) {
57         msg_format(_("充填する前に鑑定されている必要があります!", "The item must be identified first!"));
58         msg_print(NULL);
59
60         if ((player_ptr->au >= 50) && get_check(_("$50で鑑定しますか? ", "Identify for 50 gold? ")))
61
62         {
63             player_ptr->au -= 50;
64             identify_item(player_ptr, o_ptr);
65             object_desc(player_ptr, tmp_str, o_ptr, 0);
66             msg_format(_("%s です。", "You have: %s."), tmp_str);
67
68             autopick_alter_item(player_ptr, item, FALSE);
69             building_prt_gold(player_ptr);
70         }
71
72         return;
73     }
74
75     DEPTH lev = k_info[o_ptr->k_idx].level;
76     PRICE price;
77     if (o_ptr->tval == TV_ROD) {
78         if (o_ptr->timeout > 0) {
79             price = (lev * 50 * o_ptr->timeout) / k_ptr->pval;
80         } else {
81             price = 0;
82             msg_format(_("それは再充填する必要はありません。", "That doesn't need to be recharged."));
83             return;
84         }
85     } else if (o_ptr->tval == TV_STAFF) {
86         price = (k_info[o_ptr->k_idx].cost / 10) * o_ptr->number;
87         price = MAX(10, price);
88     } else {
89         price = (k_info[o_ptr->k_idx].cost / 10);
90         price = MAX(10, price);
91     }
92
93     if (o_ptr->tval == TV_WAND && (o_ptr->pval / o_ptr->number >= k_ptr->pval)) {
94         if (o_ptr->number > 1) {
95             msg_print(_("この魔法棒はもう充分に充填されています。", "These wands are already fully charged."));
96         } else {
97             msg_print(_("この魔法棒はもう充分に充填されています。", "This wand is already fully charged."));
98         }
99
100         return;
101     } else if (o_ptr->tval == TV_STAFF && o_ptr->pval >= k_ptr->pval) {
102         if (o_ptr->number > 1) {
103             msg_print(_("この杖はもう充分に充填されています。", "These staffs are already fully charged."));
104         } else {
105             msg_print(_("この杖はもう充分に充填されています。", "This staff is already fully charged."));
106         }
107
108         return;
109     }
110
111     if (player_ptr->au < price) {
112         object_desc(player_ptr, tmp_str, o_ptr, OD_NAME_ONLY);
113 #ifdef JP
114         msg_format("%sを再充填するには$%d 必要です!", tmp_str, price);
115 #else
116         msg_format("You need %d gold to recharge %s!", price, tmp_str);
117 #endif
118         return;
119     }
120
121     PARAMETER_VALUE charges;
122     if (o_ptr->tval == TV_ROD) {
123 #ifdef JP
124         if (get_check(format("そのロッドを$%d で再充填しますか?", price)))
125 #else
126         if (get_check(format("Recharge the %s for %d gold? ", ((o_ptr->number > 1) ? "rods" : "rod"), price)))
127 #endif
128
129         {
130             o_ptr->timeout = 0;
131         } else {
132             return;
133         }
134     } else {
135         int max_charges;
136         if (o_ptr->tval == TV_STAFF)
137             max_charges = k_ptr->pval - o_ptr->pval;
138         else
139             max_charges = o_ptr->number * k_ptr->pval - o_ptr->pval;
140
141         charges = (PARAMETER_VALUE)get_quantity(
142             format(_("一回分$%d で何回分充填しますか?", "Add how many charges for %d gold? "), price), MIN(player_ptr->au / price, max_charges));
143
144         if (charges < 1)
145             return;
146
147         price *= charges;
148         o_ptr->pval += charges;
149         o_ptr->ident &= ~(IDENT_EMPTY);
150     }
151
152     object_desc(player_ptr, tmp_str, o_ptr, 0);
153 #ifdef JP
154     msg_format("%sを$%d で再充填しました。", tmp_str, price);
155 #else
156     msg_format("%^s %s recharged for %d gold.", tmp_str, ((o_ptr->number > 1) ? "were" : "was"), price);
157 #endif
158     player_ptr->update |= (PU_COMBINE | PU_REORDER);
159     player_ptr->window |= (PW_INVEN);
160     player_ptr->au -= price;
161 }
162
163 /*!
164  * @brief 魔道具の使用回数を回復させる施設の一括処理向けサブルーチン / Recharge rods, wands and staffs
165  * @details
166  * The player can select the number of charges to add\n
167  * (up to a limit), and the recharge never fails.\n
168  *\n
169  * The cost for rods depends on the level of the rod. The prices\n
170  * for recharging wands and staffs are dependent on the cost of\n
171  * the base-item.\n
172  * @param player_ptr プレーヤーへの参照ポインタ
173  * @return なし
174  */
175 void building_recharge_all(player_type *player_ptr)
176 {
177     msg_flag = FALSE;
178     clear_bldg(4, 18);
179     prt(_("  再充填の費用はアイテムの種類によります。", "  The prices of recharge depend on the type."), 6, 0);
180
181     PRICE price = 0;
182     PRICE total_cost = 0;
183     for (INVENTORY_IDX i = 0; i < INVEN_PACK; i++) {
184         object_type *o_ptr;
185         o_ptr = &player_ptr->inventory_list[i];
186
187         if (o_ptr->tval < TV_STAFF || o_ptr->tval > TV_ROD)
188             continue;
189         if (!object_is_known(o_ptr))
190             total_cost += 50;
191
192         DEPTH lev = k_info[o_ptr->k_idx].level;
193         object_kind *k_ptr;
194         k_ptr = &k_info[o_ptr->k_idx];
195
196         switch (o_ptr->tval) {
197         case TV_ROD:
198             price = (lev * 50 * o_ptr->timeout) / k_ptr->pval;
199             break;
200
201         case TV_STAFF:
202             price = (k_info[o_ptr->k_idx].cost / 10) * o_ptr->number;
203             price = MAX(10, price);
204             price = (k_ptr->pval - o_ptr->pval) * price;
205             break;
206
207         case TV_WAND:
208             price = (k_info[o_ptr->k_idx].cost / 10);
209             price = MAX(10, price);
210             price = (o_ptr->number * k_ptr->pval - o_ptr->pval) * price;
211             break;
212         }
213
214         if (price > 0)
215             total_cost += price;
216     }
217
218     if (!total_cost) {
219         msg_print(_("充填する必要はありません。", "No need to recharge."));
220         msg_print(NULL);
221         return;
222     }
223
224     if (player_ptr->au < total_cost) {
225         msg_format(_("すべてのアイテムを再充填するには$%d 必要です!", "You need %d gold to recharge all items!"), total_cost);
226         msg_print(NULL);
227         return;
228     }
229
230     if (!get_check(format(_("すべてのアイテムを $%d で再充填しますか?", "Recharge all items for %d gold? "), total_cost)))
231         return;
232
233     for (INVENTORY_IDX i = 0; i < INVEN_PACK; i++) {
234         object_type *o_ptr;
235         o_ptr = &player_ptr->inventory_list[i];
236         object_kind *k_ptr;
237         k_ptr = &k_info[o_ptr->k_idx];
238
239         if (o_ptr->tval < TV_STAFF || o_ptr->tval > TV_ROD)
240             continue;
241
242         if (!object_is_known(o_ptr)) {
243             identify_item(player_ptr, o_ptr);
244             autopick_alter_item(player_ptr, i, FALSE);
245         }
246
247         switch (o_ptr->tval) {
248         case TV_ROD:
249             o_ptr->timeout = 0;
250             break;
251         case TV_STAFF:
252             if (o_ptr->pval < k_ptr->pval)
253                 o_ptr->pval = k_ptr->pval;
254
255             o_ptr->ident &= ~(IDENT_EMPTY);
256             break;
257         case TV_WAND:
258             if (o_ptr->pval < o_ptr->number * k_ptr->pval)
259                 o_ptr->pval = o_ptr->number * k_ptr->pval;
260
261             o_ptr->ident &= ~(IDENT_EMPTY);
262             break;
263         }
264     }
265
266     msg_format(_("$%d で再充填しました。", "You pay %d gold."), total_cost);
267     msg_print(NULL);
268     player_ptr->update |= (PU_COMBINE | PU_REORDER);
269     player_ptr->window |= (PW_INVEN);
270     player_ptr->au -= total_cost;
271 }