OSDN Git Service

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