OSDN Git Service

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