OSDN Git Service

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