OSDN Git Service

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