2 * @brief 魔法効果の実装/ Spell code (part 3)
6 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7 * This software may be copied and distributed for educational, research,
8 * and not for profit purposes provided that this copyright and statement
9 * are included in all such copies. Other copyrights may also apply.
13 #include "spell-kind/magic-item-recharger.h"
14 #include "core/stuff-handler.h"
15 #include "flavor/flavor-describer.h"
16 #include "flavor/object-flavor-types.h"
17 #include "floor/floor-object.h"
18 #include "inventory/inventory-object.h"
19 #include "object-enchant/special-object-flags.h"
20 #include "object-hook/hook-magic.h"
21 #include "object/item-tester-hooker.h"
22 #include "object/item-use-flags.h"
23 #include "player-base/player-class.h"
24 #include "system/angband-exceptions.h"
25 #include "system/baseitem-info.h"
26 #include "system/item-entity.h"
27 #include "system/player-type-definition.h"
28 #include "view/display-messages.h"
32 * Recharge a wand/staff/rod from the pack or on the floor.
33 * This function has been rewritten in Oangband and ZAngband.
34 * @param player_ptr プレイヤーへの参照ポインタ
36 * @return ターン消費を要する処理まで進んだらTRUEを返す
38 * Sorcery/Arcane -- Recharge --> recharge(plev * 4)
39 * Chaos -- Arcane Binding --> recharge(90)
41 * Scroll of recharging --> recharge(130)
42 * Artifact activation/Thingol --> recharge(130)
44 * It is harder to recharge high level, and highly charged wands,
45 * staffs, and rods. The more wands in a stack, the more easily and
46 * strongly they recharge. Staffs, however, each get fewer charges if
49 * Beware of "sliding index errors".
51 bool recharge(PlayerType *player_ptr, int power)
53 concptr q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
54 concptr s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
57 auto *o_ptr = choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), FuncItemTester(&ItemEntity::can_recharge));
58 if (o_ptr == nullptr) {
62 const auto &baseitem = o_ptr->get_baseitem();
63 const auto lev = baseitem.level;
65 TIME_EFFECT recharge_amount;
66 int recharge_strength;
67 auto is_recharge_successful = true;
68 const auto tval = o_ptr->bi_key.tval();
69 if (tval == ItemKindType::ROD) {
70 recharge_strength = ((power > lev / 2) ? (power - lev / 2) : 0) / 5;
71 if (one_in_(recharge_strength)) {
72 is_recharge_successful = false;
74 recharge_amount = (power * damroll(3, 2));
75 if (o_ptr->timeout > recharge_amount) {
76 o_ptr->timeout -= recharge_amount;
82 if ((tval == ItemKindType::WAND) && (o_ptr->number > 1)) {
83 recharge_strength = (100 + power - lev - (8 * o_ptr->pval / o_ptr->number)) / 15;
85 recharge_strength = (100 + power - lev - (8 * o_ptr->pval)) / 15;
88 if (recharge_strength < 0) {
89 recharge_strength = 0;
92 if (one_in_(recharge_strength)) {
93 is_recharge_successful = false;
95 recharge_amount = randint1(1 + baseitem.pval / 2);
96 if ((tval == ItemKindType::WAND) && (o_ptr->number > 1)) {
97 recharge_amount += (randint1(recharge_amount * (o_ptr->number - 1))) / 2;
98 if (recharge_amount < 1) {
101 if (recharge_amount > 12) {
102 recharge_amount = 12;
106 if ((tval == ItemKindType::STAFF) && (o_ptr->number > 1)) {
107 recharge_amount /= (TIME_EFFECT)o_ptr->number;
108 if (recharge_amount < 1) {
113 o_ptr->pval += recharge_amount;
114 o_ptr->ident &= ~(IDENT_KNOWN);
115 o_ptr->ident &= ~(IDENT_EMPTY);
119 if (is_recharge_successful) {
120 return update_player();
123 if (o_ptr->is_fixed_artifact()) {
124 const auto item_name = describe_flavor(player_ptr, o_ptr, OD_NAME_ONLY);
125 msg_format(_("魔力が逆流した!%sは完全に魔力を失った。", "The recharging backfires - %s is completely drained!"), item_name.data());
126 if ((tval == ItemKindType::ROD) && (o_ptr->timeout < 10000)) {
127 o_ptr->timeout = (o_ptr->timeout + 100) * 2;
128 } else if (o_ptr->is_wand_staff()) {
131 return update_player();
134 const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
136 if (PlayerClass(player_ptr).is_wizard()) {
137 /* 10% chance to blow up one rod, otherwise draining. */
138 if (tval == ItemKindType::ROD) {
145 /* 75% chance to blow up one wand, otherwise draining. */
146 else if (tval == ItemKindType::WAND) {
153 /* 50% chance to blow up one staff, otherwise no effect. */
154 else if (tval == ItemKindType::STAFF) {
162 /* 33% chance to blow up one rod, otherwise draining. */
163 if (tval == ItemKindType::ROD) {
170 /* 20% chance of the entire stack, else destroy one wand. */
171 else if (tval == ItemKindType::WAND) {
178 /* Blow up one staff. */
179 else if (tval == ItemKindType::STAFF) {
188 if (tval == ItemKindType::ROD) {
189 msg_print(_("魔力が逆噴射して、ロッドからさらに魔力を吸い取ってしまった!", "The recharge backfires, draining the rod further!"));
191 if (o_ptr->timeout < 10000) {
192 o_ptr->timeout = (o_ptr->timeout + 100) * 2;
194 } else if (tval == ItemKindType::WAND) {
195 msg_format(_("%sは破損を免れたが、魔力が全て失われた。", "You save your %s from destruction, but all charges are lost."), item_name.data());
201 if (o_ptr->number > 1) {
202 msg_format(_("乱暴な魔法のために%sが一本壊れた!", "Wild magic consumes one of your %s!"), item_name.data());
204 msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), item_name.data());
207 if (tval == ItemKindType::ROD) {
208 o_ptr->timeout = (o_ptr->number - 1) * baseitem.pval;
211 if (tval == ItemKindType::WAND) {
215 vary_item(player_ptr, item, -1);
218 if (o_ptr->number > 1) {
219 msg_format(_("乱暴な魔法のために%sが全て壊れた!", "Wild magic consumes all your %s!"), item_name.data());
221 msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), item_name.data());
224 vary_item(player_ptr, item, -999);
227 THROW_EXCEPTION(std::logic_error, "Invalid fail type!");
230 return update_player();