OSDN Git Service

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