OSDN Git Service

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