OSDN Git Service

b26830774360929c1093b70a5a62637555b49f5c
[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     const auto q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
40     const auto s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
41     OBJECT_IDX item;
42     auto *o_ptr = choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), FuncItemTester(&ItemEntity::can_recharge));
43     if (o_ptr == nullptr) {
44         return;
45     }
46
47     /*
48      * We don't want to give the player free info about
49      * the level of the item or the number of charges.
50      */
51     if (!o_ptr->is_known()) {
52         msg_format(_("充填する前に鑑定されている必要があります!", "The item must be identified first!"));
53         msg_print(nullptr);
54         if ((player_ptr->au >= 50) && get_check(_("$50で鑑定しますか? ", "Identify for 50 gold? "))) {
55             player_ptr->au -= 50;
56             identify_item(player_ptr, o_ptr);
57             const auto item_name = describe_flavor(player_ptr, o_ptr, 0);
58             msg_format(_("%s です。", "You have: %s."), item_name.data());
59             autopick_alter_item(player_ptr, item, false);
60             building_prt_gold(player_ptr);
61         }
62
63         return;
64     }
65
66     const auto &baseitem = o_ptr->get_baseitem();
67     const auto lev = baseitem.level;
68     const auto tval = o_ptr->bi_key.tval();
69     int price;
70     switch (tval) {
71     case ItemKindType::ROD:
72         if (o_ptr->timeout > 0) {
73             price = (lev * 50 * o_ptr->timeout) / baseitem.pval;
74             break;
75         }
76
77         price = 0;
78         msg_format(_("それは再充填する必要はありません。", "That doesn't need to be recharged."));
79         return;
80     case ItemKindType::STAFF:
81         price = (baseitem.cost / 10) * o_ptr->number;
82         price = std::max(10, price);
83         break;
84     default:
85         price = baseitem.cost / 10;
86         price = std::max(10, price);
87         break;
88     }
89
90     if ((tval == ItemKindType::WAND) && (o_ptr->pval / o_ptr->number >= baseitem.pval)) {
91         if (o_ptr->number > 1) {
92             msg_print(_("この魔法棒はもう充分に充填されています。", "These wands are already fully charged."));
93         } else {
94             msg_print(_("この魔法棒はもう充分に充填されています。", "This wand is already fully charged."));
95         }
96
97         return;
98     } else if ((tval == ItemKindType::STAFF) && o_ptr->pval >= baseitem.pval) {
99         if (o_ptr->number > 1) {
100             msg_print(_("この杖はもう充分に充填されています。", "These staffs are already fully charged."));
101         } else {
102             msg_print(_("この杖はもう充分に充填されています。", "This staff is already fully charged."));
103         }
104
105         return;
106     }
107
108     if (player_ptr->au < price) {
109         const auto item_name = describe_flavor(player_ptr, o_ptr, OD_NAME_ONLY);
110 #ifdef JP
111         msg_format("%sを再充填するには$%d 必要です!", item_name.data(), price);
112 #else
113         msg_format("You need %d gold to recharge %s!", price, item_name.data());
114 #endif
115         return;
116     }
117
118     if (tval == ItemKindType::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 (tval == ItemKindType::STAFF) {
133             max_charges = baseitem.pval - o_ptr->pval;
134         } else {
135             max_charges = o_ptr->number * baseitem.pval - o_ptr->pval;
136         }
137
138         const auto mes = _("一回分$%d で何回分充填しますか?", "Add how many charges for %d gold apiece? ");
139         const auto charges = get_quantity(format(mes, price), std::min(player_ptr->au / price, max_charges));
140         if (charges < 1) {
141             return;
142         }
143
144         price *= charges;
145         o_ptr->pval += static_cast<short>(charges);
146         o_ptr->ident &= ~(IDENT_EMPTY);
147     }
148
149     const auto item_name = describe_flavor(player_ptr, o_ptr, 0);
150 #ifdef JP
151     msg_format("%sを$%d で再充填しました。", item_name.data(), price);
152 #else
153     msg_format("%s^ %s recharged for %d gold.", item_name.data(), ((o_ptr->number > 1) ? "were" : "was"), price);
154 #endif
155     player_ptr->update |= (PU_COMBINATION | PU_REORDER);
156     player_ptr->window_flags |= (PW_INVENTORY);
157     player_ptr->au -= price;
158 }
159
160 /*!
161  * @brief 魔道具の使用回数を回復させる施設の一括処理向けサブルーチン / Recharge rods, wands and staffs
162  * @details
163  * The player can select the number of charges to add\n
164  * (up to a limit), and the recharge never fails.\n
165  *\n
166  * The cost for rods depends on the level of the rod. The prices\n
167  * for recharging wands and staffs are dependent on the cost of\n
168  * the base-item.\n
169  * @param player_ptr プレイヤーへの参照ポインタ
170  */
171 void building_recharge_all(PlayerType *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     auto price = 0;
178     auto total_cost = 0;
179     for (short i = 0; i < INVEN_PACK; i++) {
180         const auto &item = player_ptr->inventory_list[i];
181         if (!item.can_recharge()) {
182             continue;
183         }
184
185         if (!item.is_known()) {
186             total_cost += 50;
187         }
188
189         const auto &baseitem = item.get_baseitem();
190         const auto lev = baseitem.level;
191         switch (item.bi_key.tval()) {
192         case ItemKindType::ROD:
193             price = (lev * 50 * item.timeout) / baseitem.pval;
194             break;
195         case ItemKindType::STAFF:
196             price = (baseitem.cost / 10) * item.number;
197             price = std::max(10, price);
198             price = (baseitem.pval - item.pval) * price;
199             break;
200         case ItemKindType::WAND:
201             price = (baseitem.cost / 10);
202             price = std::max(10, price);
203             price = (item.number * baseitem.pval - item.pval) * price;
204             break;
205         default:
206             break;
207         }
208
209         if (price > 0) {
210             total_cost += price;
211         }
212     }
213
214     if (!total_cost) {
215         msg_print(_("充填する必要はありません。", "No need to recharge."));
216         msg_print(nullptr);
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(nullptr);
223         return;
224     }
225
226     if (!get_check(format(_("すべてのアイテムを $%d で再充填しますか?", "Recharge all items for %d gold? "), total_cost))) {
227         return;
228     }
229
230     for (short i = 0; i < INVEN_PACK; i++) {
231         auto *o_ptr = &player_ptr->inventory_list[i];
232         const auto &baseitem = o_ptr->get_baseitem();
233         if (!o_ptr->can_recharge()) {
234             continue;
235         }
236
237         if (!o_ptr->is_known()) {
238             identify_item(player_ptr, o_ptr);
239             autopick_alter_item(player_ptr, i, false);
240         }
241
242         switch (o_ptr->bi_key.tval()) {
243         case ItemKindType::ROD:
244             o_ptr->timeout = 0;
245             break;
246         case ItemKindType::STAFF:
247             if (o_ptr->pval < baseitem.pval) {
248                 o_ptr->pval = baseitem.pval;
249             }
250
251             o_ptr->ident &= ~(IDENT_EMPTY);
252             break;
253         case ItemKindType::WAND:
254             if (o_ptr->pval < o_ptr->number * baseitem.pval) {
255                 o_ptr->pval = o_ptr->number * baseitem.pval;
256             }
257
258             o_ptr->ident &= ~(IDENT_EMPTY);
259             break;
260         default:
261             break;
262         }
263     }
264
265     msg_format(_("$%d で再充填しました。", "You pay %d gold."), total_cost);
266     msg_print(nullptr);
267     player_ptr->update |= (PU_COMBINATION | PU_REORDER);
268     player_ptr->window_flags |= (PW_INVENTORY);
269     player_ptr->au -= total_cost;
270 }