OSDN Git Service

[Fix] モンスターの経験値表示に不具合 #155
[hengbandforosx/hengbandosx.git] / src / spell-kind / magic-item-recharger.c
1 /*!
2  * @brief 魔法効果の実装/ Spell code (part 3)
3  * @date 2014/07/26
4  * @author
5  * <pre>
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.
10  * </pre>
11  */
12
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-enchant.h"
21 #include "object-hook/hook-magic.h"
22 #include "object/item-tester-hooker.h"
23 #include "object/item-use-flags.h"
24 #include "object/object-kind.h"
25 #include "player/player-realm.h"
26 #include "view/display-messages.h"
27
28 /*!
29  * @brief 魔力充填処理 /
30  * Recharge a wand/staff/rod from the pack or on the floor.
31  * This function has been rewritten in Oangband and ZAngband.
32  * @param caster_ptr プレーヤーへの参照ポインタ
33  * @param power 充填パワー
34  * @return ターン消費を要する処理まで進んだらTRUEを返す
35  *
36  * Sorcery/Arcane -- Recharge  --> recharge(plev * 4)
37  * Chaos -- Arcane Binding     --> recharge(90)
38  *
39  * Scroll of recharging        --> recharge(130)
40  * Artifact activation/Thingol --> recharge(130)
41  *
42  * It is harder to recharge high level, and highly charged wands,
43  * staffs, and rods.  The more wands in a stack, the more easily and
44  * strongly they recharge.  Staffs, however, each get fewer charges if
45  * stacked.
46  *
47  * Beware of "sliding index errors".
48  */
49 bool recharge(player_type *caster_ptr, int power)
50 {
51     item_tester_hook = item_tester_hook_recharge;
52     concptr q = _("どのアイテムに魔力を充填しますか? ", "Recharge which item? ");
53     concptr s = _("魔力を充填すべきアイテムがない。", "You have nothing to recharge.");
54
55     OBJECT_IDX item;
56     object_type *o_ptr;
57     o_ptr = choose_object(caster_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
58     if (!o_ptr)
59         return FALSE;
60
61     object_kind *k_ptr;
62     k_ptr = &k_info[o_ptr->k_idx];
63     DEPTH lev = k_info[o_ptr->k_idx].level;
64
65     TIME_EFFECT recharge_amount;
66     int recharge_strength;
67     bool is_recharge_successful = TRUE;
68     if (o_ptr->tval == TV_ROD) {
69         recharge_strength = ((power > lev / 2) ? (power - lev / 2) : 0) / 5;
70         if (one_in_(recharge_strength)) {
71             is_recharge_successful = FALSE;
72         } else {
73             recharge_amount = (power * damroll(3, 2));
74             if (o_ptr->timeout > recharge_amount)
75                 o_ptr->timeout -= recharge_amount;
76             else
77                 o_ptr->timeout = 0;
78         }
79     } else {
80         if ((o_ptr->tval == TV_WAND) && (o_ptr->number > 1))
81             recharge_strength = (100 + power - lev - (8 * o_ptr->pval / o_ptr->number)) / 15;
82         else
83             recharge_strength = (100 + power - lev - (8 * o_ptr->pval)) / 15;
84
85         if (recharge_strength < 0)
86             recharge_strength = 0;
87
88         if (one_in_(recharge_strength)) {
89             is_recharge_successful = FALSE;
90         } else {
91             recharge_amount = randint1(1 + k_ptr->pval / 2);
92             if ((o_ptr->tval == TV_WAND) && (o_ptr->number > 1)) {
93                 recharge_amount += (randint1(recharge_amount * (o_ptr->number - 1))) / 2;
94                 if (recharge_amount < 1)
95                     recharge_amount = 1;
96                 if (recharge_amount > 12)
97                     recharge_amount = 12;
98             }
99
100             if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1)) {
101                 recharge_amount /= (TIME_EFFECT)o_ptr->number;
102                 if (recharge_amount < 1)
103                     recharge_amount = 1;
104             }
105
106             o_ptr->pval += recharge_amount;
107             o_ptr->ident &= ~(IDENT_KNOWN);
108             o_ptr->ident &= ~(IDENT_EMPTY);
109         }
110     }
111
112     if (is_recharge_successful) {
113         return update_player(caster_ptr);
114     }
115
116     byte fail_type = 1;
117     GAME_TEXT o_name[MAX_NLEN];
118     if (object_is_fixed_artifact(o_ptr)) {
119         describe_flavor(caster_ptr, o_name, o_ptr, OD_NAME_ONLY);
120         msg_format(_("魔力が逆流した!%sは完全に魔力を失った。", "The recharging backfires - %s is completely drained!"), o_name);
121         if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout < 10000))
122             o_ptr->timeout = (o_ptr->timeout + 100) * 2;
123         else if ((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF))
124             o_ptr->pval = 0;
125         return update_player(caster_ptr);
126     }
127
128     describe_flavor(caster_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
129
130     if (is_wizard_class(caster_ptr) || caster_ptr->pclass == CLASS_MAGIC_EATER || caster_ptr->pclass == CLASS_BLUE_MAGE) {
131         /* 10% chance to blow up one rod, otherwise draining. */
132         if (o_ptr->tval == TV_ROD) {
133             if (one_in_(10))
134                 fail_type = 2;
135             else
136                 fail_type = 1;
137         }
138         /* 75% chance to blow up one wand, otherwise draining. */
139         else if (o_ptr->tval == TV_WAND) {
140             if (!one_in_(3))
141                 fail_type = 2;
142             else
143                 fail_type = 1;
144         }
145         /* 50% chance to blow up one staff, otherwise no effect. */
146         else if (o_ptr->tval == TV_STAFF) {
147             if (one_in_(2))
148                 fail_type = 2;
149             else
150                 fail_type = 0;
151         }
152     } else {
153         /* 33% chance to blow up one rod, otherwise draining. */
154         if (o_ptr->tval == TV_ROD) {
155             if (one_in_(3))
156                 fail_type = 2;
157             else
158                 fail_type = 1;
159         }
160         /* 20% chance of the entire stack, else destroy one wand. */
161         else if (o_ptr->tval == TV_WAND) {
162             if (one_in_(5))
163                 fail_type = 3;
164             else
165                 fail_type = 2;
166         }
167         /* Blow up one staff. */
168         else if (o_ptr->tval == TV_STAFF) {
169             fail_type = 2;
170         }
171     }
172
173     if (fail_type == 1) {
174         if (o_ptr->tval == TV_ROD) {
175             msg_print(_("魔力が逆噴射して、ロッドからさらに魔力を吸い取ってしまった!", "The recharge backfires, draining the rod further!"));
176
177             if (o_ptr->timeout < 10000)
178                 o_ptr->timeout = (o_ptr->timeout + 100) * 2;
179         } else if (o_ptr->tval == TV_WAND) {
180             msg_format(_("%sは破損を免れたが、魔力が全て失われた。", "You save your %s from destruction, but all charges are lost."), o_name);
181             o_ptr->pval = 0;
182         }
183     }
184
185     if (fail_type == 2) {
186         if (o_ptr->number > 1)
187             msg_format(_("乱暴な魔法のために%sが一本壊れた!", "Wild magic consumes one of your %s!"), o_name);
188         else
189             msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
190
191         if (o_ptr->tval == TV_ROD)
192             o_ptr->timeout = (o_ptr->number - 1) * k_ptr->pval;
193         if (o_ptr->tval == TV_WAND)
194             o_ptr->pval = 0;
195
196         vary_item(caster_ptr, item, -1);
197     }
198
199     if (fail_type == 3) {
200         if (o_ptr->number > 1)
201             msg_format(_("乱暴な魔法のために%sが全て壊れた!", "Wild magic consumes all your %s!"), o_name);
202         else
203             msg_format(_("乱暴な魔法のために%sが壊れた!", "Wild magic consumes your %s!"), o_name);
204
205         vary_item(caster_ptr, item, -999);
206     }
207
208     return update_player(caster_ptr);
209 }