2 * @brief ベースアイテムを強化する処理
8 #include "object-enchant/apply-magic.h"
9 #include "artifact/fixed-art-types.h"
10 #include "artifact/fixed-art-generator.h"
11 #include "dungeon/dungeon.h"
12 #include "mutation/mutation-flag-types.h"
13 #include "object-enchant/apply-magic-accessory.h"
14 #include "object-enchant/apply-magic-armor.h"
15 #include "object-enchant/apply-magic-others.h"
16 #include "object-enchant/apply-magic-weapon.h"
17 #include "object-enchant/item-apply-magic.h"
18 #include "object-enchant/object-boost.h"
19 #include "object-enchant/object-curse.h"
20 #include "object-enchant/object-ego.h"
21 #include "object-enchant/special-object-flags.h"
22 #include "object-enchant/tr-types.h"
23 #include "object-enchant/trc-types.h"
24 #include "object-enchant/trg-types.h"
25 #include "object-hook/hook-checker.h"
26 #include "object-hook/hook-enchant.h"
27 #include "object/object-kind.h"
28 #include "player/player-status-flags.h"
29 #include "sv-definition/sv-armor-types.h"
30 #include "sv-definition/sv-protector-types.h"
31 #include "sv-definition/sv-weapon-types.h"
32 #include "system/artifact-type-definition.h"
33 #include "system/floor-type-definition.h"
34 #include "util/bit-flags-calculator.h"
35 #include "world/world.h"
38 * @brief 0 および負数に対応した randint1()
41 * n == 0 のとき、常に 0 を返す。
42 * n > 0 のとき、[1, n] の乱数を返す。
43 * n < 0 のとき、[n,-1] の乱数を返す。
45 static int randint1_signed(const int n)
50 return n > 0 ? randint1(n) : -randint1(-n);
54 * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
55 * Complete the "creation" of an object by applying "magic" to the item
56 * @param owner_ptr プレーヤーへの参照ポインタ
57 * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
62 * エゴ&アーティファクトの生成、呪い、pval強化
64 void apply_magic(player_type *owner_ptr, object_type *o_ptr, DEPTH lev, BIT_FLAGS mode)
66 if (owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)
67 lev += randint0(owner_ptr->lev / 2 + 10);
68 if (lev > MAX_DEPTH - 1)
72 if (f1 > d_info[owner_ptr->dungeon_idx].obj_good)
73 f1 = d_info[owner_ptr->dungeon_idx].obj_good;
76 if ((owner_ptr->pseikaku != PERSONALITY_MUNCHKIN) && (f2 > d_info[owner_ptr->dungeon_idx].obj_great))
77 f2 = d_info[owner_ptr->dungeon_idx].obj_great;
79 if (has_good_luck(owner_ptr)) {
82 } else if (owner_ptr->muta.has(MUTA::BAD_LUCK)) {
88 if ((mode & AM_GOOD) || magik(f1)) {
90 if ((mode & AM_GREAT) || magik(f2)) {
92 if (mode & AM_SPECIAL)
95 } else if (magik(f1)) {
100 if (mode & AM_CURSED) {
112 if (mode & (AM_GREAT | AM_SPECIAL))
114 if ((mode & AM_NO_FIXED_ART) || o_ptr->name1)
117 for (int i = 0; i < rolls; i++) {
118 if (make_artifact(owner_ptr, o_ptr))
120 if (has_good_luck(owner_ptr) && one_in_(77)) {
121 if (make_artifact(owner_ptr, o_ptr))
126 if (object_is_fixed_artifact(o_ptr)) {
127 artifact_type *a_ptr = apply_artifact(owner_ptr, o_ptr);
129 if (current_world_ptr->character_dungeon)
130 a_ptr->floor_id = owner_ptr->floor_id;
134 switch (o_ptr->tval) {
142 apply_magic_weapon(owner_ptr, o_ptr, lev, power);
146 if (power && !(o_ptr->sval == SV_DEATH_SCYTHE))
147 apply_magic_weapon(owner_ptr, o_ptr, lev, power);
151 if (power && !(o_ptr->sval == SV_POISON_NEEDLE))
152 apply_magic_weapon(owner_ptr, o_ptr, lev, power);
164 if (((o_ptr->tval == TV_CLOAK) && (o_ptr->sval == SV_ELVEN_CLOAK)) || ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_KUROSHOUZOKU)))
165 o_ptr->pval = randint1(4);
167 if (power || ((o_ptr->tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM)) || ((o_ptr->tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
168 || ((o_ptr->tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
169 || ((o_ptr->tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE)))
170 apply_magic_armor(owner_ptr, o_ptr, lev, power);
176 if (!power && (randint0(100) < 50))
178 apply_magic_accessary(owner_ptr, o_ptr, lev, power);
182 apply_magic_others(owner_ptr, o_ptr, power);
187 if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (owner_ptr->pseikaku == PERSONALITY_SEXY)) {
189 add_flag(o_ptr->art_flags, TR_STR);
190 add_flag(o_ptr->art_flags, TR_INT);
191 add_flag(o_ptr->art_flags, TR_WIS);
192 add_flag(o_ptr->art_flags, TR_DEX);
193 add_flag(o_ptr->art_flags, TR_CON);
194 add_flag(o_ptr->art_flags, TR_CHR);
197 if (object_is_ego(o_ptr)) {
198 ego_item_type *e_ptr = &e_info[o_ptr->name2];
200 o_ptr->ident |= (IDENT_BROKEN);
202 if (e_ptr->gen_flags.has(TRG::CURSED))
203 o_ptr->curse_flags |= (TRC_CURSED);
204 if (e_ptr->gen_flags.has(TRG::HEAVY_CURSE))
205 o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
206 if (e_ptr->gen_flags.has(TRG::PERMA_CURSE))
207 o_ptr->curse_flags |= (TRC_PERMA_CURSE);
208 if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
209 o_ptr->curse_flags |= get_curse(owner_ptr, 0, o_ptr);
210 if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
211 o_ptr->curse_flags |= get_curse(owner_ptr, 1, o_ptr);
212 if (e_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
213 o_ptr->curse_flags |= get_curse(owner_ptr, 2, o_ptr);
215 if (e_ptr->gen_flags.has(TRG::ONE_SUSTAIN))
217 if (e_ptr->gen_flags.has(TRG::XTRA_POWER))
219 if (e_ptr->gen_flags.has(TRG::XTRA_H_RES))
220 one_high_resistance(o_ptr);
221 if (e_ptr->gen_flags.has(TRG::XTRA_E_RES))
222 one_ele_resistance(o_ptr);
223 if (e_ptr->gen_flags.has(TRG::XTRA_D_RES))
224 one_dragon_ele_resistance(o_ptr);
225 if (e_ptr->gen_flags.has(TRG::XTRA_L_RES))
226 one_lordly_high_resistance(o_ptr);
227 if (e_ptr->gen_flags.has(TRG::XTRA_RES))
228 one_resistance(o_ptr);
229 if (e_ptr->gen_flags.has(TRG::XTRA_DICE)) {
232 } while (one_in_(o_ptr->dd));
239 o_ptr->xtra2 = (XTRA8)e_ptr->act_idx;
241 bool is_powerful = e_ptr->gen_flags.has(TRG::POWERFUL);
243 if ((object_is_cursed(o_ptr) || object_is_broken(o_ptr)) && !is_powerful) {
245 o_ptr->to_h -= randint1(e_ptr->max_to_h);
247 o_ptr->to_d -= randint1(e_ptr->max_to_d);
249 o_ptr->to_a -= randint1(e_ptr->max_to_a);
251 o_ptr->pval -= randint1(e_ptr->max_pval);
254 if (e_ptr->max_to_h > 0 && o_ptr->to_h < 0)
255 o_ptr->to_h = 0 - o_ptr->to_h;
256 if (e_ptr->max_to_d > 0 && o_ptr->to_d < 0)
257 o_ptr->to_d = 0 - o_ptr->to_d;
258 if (e_ptr->max_to_a > 0 && o_ptr->to_a < 0)
259 o_ptr->to_a = 0 - o_ptr->to_a;
262 o_ptr->to_h += (HIT_PROB)randint1_signed(e_ptr->max_to_h);
263 o_ptr->to_d += randint1_signed(e_ptr->max_to_d);
264 o_ptr->to_a += (ARMOUR_CLASS)randint1_signed(e_ptr->max_to_a);
266 if (o_ptr->name2 == EGO_ACCURACY) {
267 while (o_ptr->to_h < o_ptr->to_d + 10) {
271 o_ptr->to_h = MAX(o_ptr->to_h, 15);
274 if (o_ptr->name2 == EGO_VELOCITY) {
275 while (o_ptr->to_d < o_ptr->to_h + 10) {
279 o_ptr->to_d = MAX(o_ptr->to_d, 15);
282 if ((o_ptr->name2 == EGO_PROTECTION) || (o_ptr->name2 == EGO_S_PROTECTION) || (o_ptr->name2 == EGO_H_PROTECTION)) {
283 o_ptr->to_a = MAX(o_ptr->to_a, 15);
286 if (e_ptr->max_pval) {
287 if ((o_ptr->name2 == EGO_HA) && (has_flag(o_ptr->art_flags, TR_BLOWS))) {
289 if ((lev > 60) && one_in_(3) && ((o_ptr->dd * (o_ptr->ds + 1)) < 15))
291 } else if (o_ptr->name2 == EGO_DEMON) {
292 if (has_flag(o_ptr->art_flags, TR_BLOWS)) {
293 o_ptr->pval += randint1(2);
295 o_ptr->pval += randint1(e_ptr->max_pval);
297 } else if (o_ptr->name2 == EGO_ATTACKS) {
298 o_ptr->pval = randint1(e_ptr->max_pval * lev / 100 + 1);
301 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA))
302 o_ptr->pval += randint1(2);
303 } else if (o_ptr->name2 == EGO_BAT) {
304 o_ptr->pval = randint1(e_ptr->max_pval);
305 if (o_ptr->sval == SV_ELVEN_CLOAK)
306 o_ptr->pval += randint1(2);
307 } else if (o_ptr->name2 == EGO_A_DEMON || o_ptr->name2 == EGO_DRUID || o_ptr->name2 == EGO_OLOG) {
308 o_ptr->pval = randint1(e_ptr->max_pval);
310 if (e_ptr->max_pval > 0)
311 o_ptr->pval += randint1(e_ptr->max_pval);
312 else if (e_ptr->max_pval < 0)
313 o_ptr->pval -= randint1(0 - e_ptr->max_pval);
317 if ((o_ptr->name2 == EGO_SPEED) && (lev < 50)) {
318 o_ptr->pval = randint1(o_ptr->pval);
321 if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA) && (o_ptr->pval > 2) && (o_ptr->name2 != EGO_ATTACKS))
329 object_kind *k_ptr = &k_info[o_ptr->k_idx];
330 if (!k_info[o_ptr->k_idx].cost)
331 o_ptr->ident |= (IDENT_BROKEN);
333 if (k_ptr->gen_flags.has(TRG::CURSED))
334 o_ptr->curse_flags |= (TRC_CURSED);
335 if (k_ptr->gen_flags.has(TRG::HEAVY_CURSE))
336 o_ptr->curse_flags |= TRC_HEAVY_CURSE;
337 if (k_ptr->gen_flags.has(TRG::PERMA_CURSE))
338 o_ptr->curse_flags |= TRC_PERMA_CURSE;
339 if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
340 o_ptr->curse_flags |= get_curse(owner_ptr, 0, o_ptr);
341 if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
342 o_ptr->curse_flags |= get_curse(owner_ptr, 1, o_ptr);
343 if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
344 o_ptr->curse_flags |= get_curse(owner_ptr, 2, o_ptr);