OSDN Git Service

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