OSDN Git Service

[Refactor] #40399 Separated apply-magic.c/h from object2.c/h
[hengband/hengband.git] / src / object-enchant / apply-magic.c
1 /*!
2  * todo 少し長い。要分割
3  * @brief ベースアイテムを強化する処理
4  * @date 2020/06/03
5  * @author Hourier
6  */
7
8 #include "object-enchant/apply-magic.h"
9 #include "dungeon/dungeon.h"
10 #include "floor/floor.h"
11 #include "object-enchant/apply-magic-accessory.h"
12 #include "object-enchant/apply-magic-armor.h"
13 #include "object-enchant/apply-magic-others.h"
14 #include "object-enchant/apply-magic-weapon.h"
15 #include "object-enchant/artifact.h"
16 #include "object-enchant/item-apply-magic.h"
17 #include "object-enchant/object-boost.h"
18 #include "object-enchant/object-curse.h"
19 #include "object-enchant/object-ego.h"
20 #include "object-enchant/special-object-flags.h"
21 #include "object-enchant/trc-types.h"
22 #include "object/object-hook.h"
23 #include "object/object-kind.h"
24 #include "sv-definition/sv-armor-types.h"
25 #include "sv-definition/sv-weapon-types.h"
26 #include "sv-definition/sv-protector-types.h"
27 #include "world/world.h"
28
29 /*!
30  * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
31  * Complete the "creation" of an object by applying "magic" to the item
32  * @param owner_ptr プレーヤーへの参照ポインタ
33  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
34  * @param lev 生成基準階
35  * @param mode 生成オプション
36  * @return なし
37  * @details
38  * エゴ&アーティファクトの生成、呪い、pval強化
39  */
40 void apply_magic(player_type *owner_ptr, object_type *o_ptr, DEPTH lev, BIT_FLAGS mode)
41 {
42     if (owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)
43         lev += randint0(owner_ptr->lev / 2 + 10);
44     if (lev > MAX_DEPTH - 1)
45         lev = MAX_DEPTH - 1;
46
47     int f1 = lev + 10;
48     if (f1 > d_info[owner_ptr->dungeon_idx].obj_good)
49         f1 = d_info[owner_ptr->dungeon_idx].obj_good;
50
51     int f2 = f1 * 2 / 3;
52     if ((owner_ptr->pseikaku != PERSONALITY_MUNCHKIN) && (f2 > d_info[owner_ptr->dungeon_idx].obj_great))
53         f2 = d_info[owner_ptr->dungeon_idx].obj_great;
54
55     if (owner_ptr->muta3 & MUT3_GOOD_LUCK) {
56         f1 += 5;
57         f2 += 2;
58     } else if (owner_ptr->muta3 & MUT3_BAD_LUCK) {
59         f1 -= 5;
60         f2 -= 2;
61     }
62
63     int power = 0;
64     if ((mode & AM_GOOD) || magik(f1)) {
65         power = 1;
66         if ((mode & AM_GREAT) || magik(f2)) {
67             power = 2;
68             if (mode & AM_SPECIAL)
69                 power = 3;
70         }
71     } else if (magik(f1)) {
72         power = -1;
73         if (magik(f2))
74             power = -2;
75     }
76     if (mode & AM_CURSED) {
77         if (power > 0) {
78             power = 0 - power;
79         } else {
80             power--;
81         }
82     }
83
84     int rolls = 0;
85     if (power >= 2)
86         rolls = 1;
87
88     if (mode & (AM_GREAT | AM_SPECIAL))
89         rolls = 4;
90     if ((mode & AM_NO_FIXED_ART) || o_ptr->name1)
91         rolls = 0;
92
93     for (int i = 0; i < rolls; i++) {
94         if (make_artifact(owner_ptr, o_ptr))
95             break;
96         if ((owner_ptr->muta3 & MUT3_GOOD_LUCK) && one_in_(77)) {
97             if (make_artifact(owner_ptr, o_ptr))
98                 break;
99         }
100     }
101
102     if (object_is_fixed_artifact(o_ptr)) {
103         artifact_type *a_ptr = &a_info[o_ptr->name1];
104         a_ptr->cur_num = 1;
105         if (current_world_ptr->character_dungeon)
106             a_ptr->floor_id = owner_ptr->floor_id;
107
108         o_ptr->pval = a_ptr->pval;
109         o_ptr->ac = a_ptr->ac;
110         o_ptr->dd = a_ptr->dd;
111         o_ptr->ds = a_ptr->ds;
112         o_ptr->to_a = a_ptr->to_a;
113         o_ptr->to_h = a_ptr->to_h;
114         o_ptr->to_d = a_ptr->to_d;
115         o_ptr->weight = a_ptr->weight;
116         o_ptr->xtra2 = a_ptr->act_idx;
117
118         if (o_ptr->name1 == ART_MILIM) {
119             if (owner_ptr->pseikaku == PERSONALITY_SEXY) {
120                 o_ptr->pval = 3;
121             }
122         }
123
124         if (!a_ptr->cost)
125             o_ptr->ident |= (IDENT_BROKEN);
126         if (a_ptr->gen_flags & TRG_CURSED)
127             o_ptr->curse_flags |= (TRC_CURSED);
128         if (a_ptr->gen_flags & TRG_HEAVY_CURSE)
129             o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
130         if (a_ptr->gen_flags & TRG_PERMA_CURSE)
131             o_ptr->curse_flags |= (TRC_PERMA_CURSE);
132         if (a_ptr->gen_flags & (TRG_RANDOM_CURSE0))
133             o_ptr->curse_flags |= get_curse(0, o_ptr);
134         if (a_ptr->gen_flags & (TRG_RANDOM_CURSE1))
135             o_ptr->curse_flags |= get_curse(1, o_ptr);
136         if (a_ptr->gen_flags & (TRG_RANDOM_CURSE2))
137             o_ptr->curse_flags |= get_curse(2, o_ptr);
138
139         return;
140     }
141
142     switch (o_ptr->tval) {
143     case TV_DIGGING:
144     case TV_HAFTED:
145     case TV_BOW:
146     case TV_SHOT:
147     case TV_ARROW:
148     case TV_BOLT: {
149         if (power)
150             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
151         break;
152     }
153     case TV_POLEARM: {
154         if (power && !(o_ptr->sval == SV_DEATH_SCYTHE))
155             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
156         break;
157     }
158     case TV_SWORD: {
159         if (power && !(o_ptr->sval == SV_POISON_NEEDLE))
160             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
161         break;
162     }
163     case TV_DRAG_ARMOR:
164     case TV_HARD_ARMOR:
165     case TV_SOFT_ARMOR:
166     case TV_SHIELD:
167     case TV_HELM:
168     case TV_CROWN:
169     case TV_CLOAK:
170     case TV_GLOVES:
171     case TV_BOOTS: {
172         if (((o_ptr->tval == TV_CLOAK) && (o_ptr->sval == SV_ELVEN_CLOAK)) || ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_KUROSHOUZOKU)))
173             o_ptr->pval = randint1(4);
174
175         if (power || ((o_ptr->tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM)) || ((o_ptr->tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
176             || ((o_ptr->tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
177             || ((o_ptr->tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE)))
178             apply_magic_armor(owner_ptr, o_ptr, lev, power);
179
180         break;
181     }
182     case TV_RING:
183     case TV_AMULET: {
184         if (!power && (randint0(100) < 50))
185             power = -1;
186         apply_magic_accessary(owner_ptr, o_ptr, lev, power);
187         break;
188     }
189     default: {
190         apply_magic_others(owner_ptr, o_ptr, power);
191         break;
192     }
193     }
194
195     if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (owner_ptr->pseikaku == PERSONALITY_SEXY)) {
196         o_ptr->pval = 3;
197         add_flag(o_ptr->art_flags, TR_STR);
198         add_flag(o_ptr->art_flags, TR_INT);
199         add_flag(o_ptr->art_flags, TR_WIS);
200         add_flag(o_ptr->art_flags, TR_DEX);
201         add_flag(o_ptr->art_flags, TR_CON);
202         add_flag(o_ptr->art_flags, TR_CHR);
203     }
204
205     if (object_is_ego(o_ptr)) {
206         ego_item_type *e_ptr = &e_info[o_ptr->name2];
207         if (!e_ptr->cost)
208             o_ptr->ident |= (IDENT_BROKEN);
209
210         if (e_ptr->gen_flags & TRG_CURSED)
211             o_ptr->curse_flags |= (TRC_CURSED);
212         if (e_ptr->gen_flags & TRG_HEAVY_CURSE)
213             o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
214         if (e_ptr->gen_flags & TRG_PERMA_CURSE)
215             o_ptr->curse_flags |= (TRC_PERMA_CURSE);
216         if (e_ptr->gen_flags & (TRG_RANDOM_CURSE0))
217             o_ptr->curse_flags |= get_curse(0, o_ptr);
218         if (e_ptr->gen_flags & (TRG_RANDOM_CURSE1))
219             o_ptr->curse_flags |= get_curse(1, o_ptr);
220         if (e_ptr->gen_flags & (TRG_RANDOM_CURSE2))
221             o_ptr->curse_flags |= get_curse(2, o_ptr);
222
223         if (e_ptr->gen_flags & (TRG_ONE_SUSTAIN))
224             one_sustain(o_ptr);
225         if (e_ptr->gen_flags & (TRG_XTRA_POWER))
226             one_ability(o_ptr);
227         if (e_ptr->gen_flags & (TRG_XTRA_H_RES))
228             one_high_resistance(o_ptr);
229         if (e_ptr->gen_flags & (TRG_XTRA_E_RES))
230             one_ele_resistance(o_ptr);
231         if (e_ptr->gen_flags & (TRG_XTRA_D_RES))
232             one_dragon_ele_resistance(o_ptr);
233         if (e_ptr->gen_flags & (TRG_XTRA_L_RES))
234             one_lordly_high_resistance(o_ptr);
235         if (e_ptr->gen_flags & (TRG_XTRA_RES))
236             one_resistance(o_ptr);
237         if (e_ptr->gen_flags & (TRG_XTRA_DICE)) {
238             do {
239                 o_ptr->dd++;
240             } while (one_in_(o_ptr->dd));
241
242             if (o_ptr->dd > 9)
243                 o_ptr->dd = 9;
244         }
245
246         if (e_ptr->act_idx)
247             o_ptr->xtra2 = (XTRA8)e_ptr->act_idx;
248
249         if ((object_is_cursed(o_ptr) || object_is_broken(o_ptr)) && !(e_ptr->gen_flags & (TRG_POWERFUL))) {
250             if (e_ptr->max_to_h)
251                 o_ptr->to_h -= randint1(e_ptr->max_to_h);
252             if (e_ptr->max_to_d)
253                 o_ptr->to_d -= randint1(e_ptr->max_to_d);
254             if (e_ptr->max_to_a)
255                 o_ptr->to_a -= randint1(e_ptr->max_to_a);
256             if (e_ptr->max_pval)
257                 o_ptr->pval -= randint1(e_ptr->max_pval);
258         } else {
259             if (e_ptr->max_to_h) {
260                 if (e_ptr->max_to_h > 127)
261                     o_ptr->to_h -= randint1(256 - e_ptr->max_to_h);
262                 else
263                     o_ptr->to_h += randint1(e_ptr->max_to_h);
264             }
265
266             if (e_ptr->max_to_d) {
267                 if (e_ptr->max_to_d > 127)
268                     o_ptr->to_d -= randint1(256 - e_ptr->max_to_d);
269                 else
270                     o_ptr->to_d += randint1(e_ptr->max_to_d);
271             }
272
273             if (e_ptr->max_to_a) {
274                 if (e_ptr->max_to_a > 127)
275                     o_ptr->to_a -= randint1(256 - e_ptr->max_to_a);
276                 else
277                     o_ptr->to_a += randint1(e_ptr->max_to_a);
278             }
279
280             if (o_ptr->name2 == EGO_ACCURACY) {
281                 while (o_ptr->to_h < o_ptr->to_d + 10) {
282                     o_ptr->to_h += 5;
283                     o_ptr->to_d -= 5;
284                 }
285                 o_ptr->to_h = MAX(o_ptr->to_h, 15);
286             }
287
288             if (o_ptr->name2 == EGO_VELOCITY) {
289                 while (o_ptr->to_d < o_ptr->to_h + 10) {
290                     o_ptr->to_d += 5;
291                     o_ptr->to_h -= 5;
292                 }
293                 o_ptr->to_d = MAX(o_ptr->to_d, 15);
294             }
295
296             if ((o_ptr->name2 == EGO_PROTECTION) || (o_ptr->name2 == EGO_S_PROTECTION) || (o_ptr->name2 == EGO_H_PROTECTION)) {
297                 o_ptr->to_a = MAX(o_ptr->to_a, 15);
298             }
299
300             if (e_ptr->max_pval) {
301                 if ((o_ptr->name2 == EGO_HA) && (have_flag(o_ptr->art_flags, TR_BLOWS))) {
302                     o_ptr->pval++;
303                     if ((lev > 60) && one_in_(3) && ((o_ptr->dd * (o_ptr->ds + 1)) < 15))
304                         o_ptr->pval++;
305                 } else if (o_ptr->name2 == EGO_DEMON) {
306                     if (have_flag(o_ptr->art_flags, TR_BLOWS)) {
307                         o_ptr->pval += randint1(2);
308                     } else {
309                         o_ptr->pval += randint1(e_ptr->max_pval);
310                     }
311                 } else if (o_ptr->name2 == EGO_ATTACKS) {
312                     o_ptr->pval = randint1(e_ptr->max_pval * lev / 100 + 1);
313                     if (o_ptr->pval > 3)
314                         o_ptr->pval = 3;
315                     if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA))
316                         o_ptr->pval += randint1(2);
317                 } else if (o_ptr->name2 == EGO_BAT) {
318                     o_ptr->pval = randint1(e_ptr->max_pval);
319                     if (o_ptr->sval == SV_ELVEN_CLOAK)
320                         o_ptr->pval += randint1(2);
321                 } else if (o_ptr->name2 == EGO_A_DEMON || o_ptr->name2 == EGO_DRUID || o_ptr->name2 == EGO_OLOG) {
322                     o_ptr->pval = randint1(e_ptr->max_pval);
323                 } else {
324                     o_ptr->pval += randint1(e_ptr->max_pval);
325                 }
326             }
327
328             if ((o_ptr->name2 == EGO_SPEED) && (lev < 50)) {
329                 o_ptr->pval = randint1(o_ptr->pval);
330             }
331
332             if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_HAYABUSA) && (o_ptr->pval > 2) && (o_ptr->name2 != EGO_ATTACKS))
333                 o_ptr->pval = 2;
334         }
335
336         return;
337     }
338
339     if (o_ptr->k_idx) {
340         object_kind *k_ptr = &k_info[o_ptr->k_idx];
341         if (!k_info[o_ptr->k_idx].cost)
342             o_ptr->ident |= (IDENT_BROKEN);
343
344         if (k_ptr->gen_flags & (TRG_CURSED))
345             o_ptr->curse_flags |= (TRC_CURSED);
346         if (k_ptr->gen_flags & (TRG_HEAVY_CURSE))
347             o_ptr->curse_flags |= TRC_HEAVY_CURSE;
348         if (k_ptr->gen_flags & (TRG_PERMA_CURSE))
349             o_ptr->curse_flags |= TRC_PERMA_CURSE;
350         if (k_ptr->gen_flags & (TRG_RANDOM_CURSE0))
351             o_ptr->curse_flags |= get_curse(0, o_ptr);
352         if (k_ptr->gen_flags & (TRG_RANDOM_CURSE1))
353             o_ptr->curse_flags |= get_curse(1, o_ptr);
354         if (k_ptr->gen_flags & (TRG_RANDOM_CURSE2))
355             o_ptr->curse_flags |= get_curse(2, o_ptr);
356     }
357 }