OSDN Git Service

[Refactor] #1301 Separated try_generate_twilight_robe() from ArmorEnchanter::apply_ma...
[hengbandforosx/hengbandosx.git] / src / object-enchant / apply-magic.cpp
1 /*!
2  * @brief ベースアイテムを強化する処理
3  * @date 2020/06/03
4  * @author Hourier
5  * @todo 少し長い。要分割
6  */
7
8 #include "object-enchant/apply-magic.h"
9 #include "artifact/fixed-art-generator.h"
10 #include "artifact/fixed-art-types.h"
11 #include "dungeon/dungeon.h"
12 #include "mutation/mutation-flag-types.h"
13 #include "object-enchant/apply-magic-amulet.h"
14 #include "object-enchant/apply-magic-armor.h"
15 #include "object-enchant/apply-magic-boots.h"
16 #include "object-enchant/apply-magic-cloak.h"
17 #include "object-enchant/apply-magic-crown.h"
18 #include "object-enchant/apply-magic-gloves.h"
19 #include "object-enchant/apply-magic-helm.h"
20 #include "object-enchant/apply-magic-others.h"
21 #include "object-enchant/apply-magic-ring.h"
22 #include "object-enchant/apply-magic-shield.h"
23 #include "object-enchant/apply-magic-weapon.h"
24 #include "object-enchant/item-apply-magic.h"
25 #include "object-enchant/object-curse.h"
26 #include "object-enchant/object-ego.h"
27 #include "object-enchant/special-object-flags.h"
28 #include "object-enchant/tr-types.h"
29 #include "object-enchant/trc-types.h"
30 #include "object-enchant/trg-types.h"
31 #include "object-hook/hook-enchant.h"
32 #include "object/object-kind.h"
33 #include "player/player-status-flags.h"
34 #include "sv-definition/sv-armor-types.h"
35 #include "sv-definition/sv-protector-types.h"
36 #include "sv-definition/sv-weapon-types.h"
37 #include "system/artifact-type-definition.h"
38 #include "system/floor-type-definition.h"
39 #include "system/player-type-definition.h"
40 #include "util/bit-flags-calculator.h"
41 #include "world/world.h"
42
43 /*!
44  * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
45  * Complete the "creation" of an object by applying "magic" to the item
46  * @param owner_ptr プレーヤーへの参照ポインタ
47  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
48  * @param lev 生成基準階
49  * @param mode 生成オプション
50  * @details
51  * エゴ&アーティファクトの生成、呪い、pval強化
52  */
53 void apply_magic_to_object(player_type *owner_ptr, object_type *o_ptr, DEPTH lev, BIT_FLAGS mode)
54 {
55     if (owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)
56         lev += randint0(owner_ptr->lev / 2 + 10);
57     if (lev > MAX_DEPTH - 1)
58         lev = MAX_DEPTH - 1;
59
60     int f1 = lev + 10;
61     if (f1 > d_info[owner_ptr->dungeon_idx].obj_good)
62         f1 = d_info[owner_ptr->dungeon_idx].obj_good;
63
64     int f2 = f1 * 2 / 3;
65     if ((owner_ptr->pseikaku != PERSONALITY_MUNCHKIN) && (f2 > d_info[owner_ptr->dungeon_idx].obj_great))
66         f2 = d_info[owner_ptr->dungeon_idx].obj_great;
67
68     if (has_good_luck(owner_ptr)) {
69         f1 += 5;
70         f2 += 2;
71     } else if (owner_ptr->muta.has(MUTA::BAD_LUCK)) {
72         f1 -= 5;
73         f2 -= 2;
74     }
75
76     int power = 0;
77     if ((mode & AM_GOOD) || magik(f1)) {
78         power = 1;
79         if ((mode & AM_GREAT) || magik(f2)) {
80             power = 2;
81             if (mode & AM_SPECIAL)
82                 power = 3;
83         }
84     } else if (magik(f1)) {
85         power = -1;
86         if (magik(f2))
87             power = -2;
88     }
89     if (mode & AM_CURSED) {
90         if (power > 0) {
91             power = 0 - power;
92         } else {
93             power--;
94         }
95     }
96
97     int rolls = 0;
98     if (power >= 2)
99         rolls = 1;
100
101     if (mode & (AM_GREAT | AM_SPECIAL))
102         rolls = 4;
103     if ((mode & AM_NO_FIXED_ART) || o_ptr->name1)
104         rolls = 0;
105
106     for (int i = 0; i < rolls; i++) {
107         if (make_artifact(owner_ptr, o_ptr))
108             break;
109         if (has_good_luck(owner_ptr) && one_in_(77)) {
110             if (make_artifact(owner_ptr, o_ptr))
111                 break;
112         }
113     }
114
115     if (object_is_fixed_artifact(o_ptr)) {
116         artifact_type *a_ptr = apply_artifact(owner_ptr, o_ptr);
117         a_ptr->cur_num = 1;
118         if (current_world_ptr->character_dungeon)
119             a_ptr->floor_id = owner_ptr->floor_id;
120         return;
121     }
122
123     switch (o_ptr->tval) {
124     case TV_DIGGING:
125     case TV_HAFTED:
126     case TV_BOW:
127     case TV_SHOT:
128     case TV_ARROW:
129     case TV_BOLT:
130         if (power != 0) {
131             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
132         }
133
134         break;
135     case TV_POLEARM:
136         if ((power != 0) && !(o_ptr->sval == SV_DEATH_SCYTHE)) {
137             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
138         }
139
140         break;
141     case TV_SWORD:
142         if ((power != 0) && !(o_ptr->sval == SV_POISON_NEEDLE)) {
143             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
144         }
145
146         break;
147     case TV_SHIELD:
148         if ((power != 0) || (o_ptr->sval == SV_DRAGON_SHIELD)) {
149             ShieldEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
150         }
151
152         break;
153     case TV_CLOAK:
154         if (o_ptr->sval == SV_ELVEN_CLOAK) {
155             o_ptr->pval = randint1(4);
156         }
157
158         if (power != 0) {
159             CloakEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
160         }
161
162         break;
163     case TV_HELM:
164         if ((power != 0) || (o_ptr->sval == SV_DRAGON_HELM)) {
165             HelmEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
166         }
167
168         break;
169     case TV_CROWN:
170         if (power != 0) {
171             CrownEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
172         }
173
174         break;
175     case TV_BOOTS:
176         if ((power != 0) || (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE)) {
177             BootsEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
178         }
179
180         break;
181     case TV_DRAG_ARMOR:
182     case TV_HARD_ARMOR:
183         if (power != 0) {
184             ArmorEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
185         }
186
187         break;
188     case TV_SOFT_ARMOR:
189         if (o_ptr->sval == SV_KUROSHOUZOKU) {
190             o_ptr->pval = randint1(4);
191         }
192
193         if (power != 0) {
194             ArmorEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
195         }
196
197         break;
198     case TV_GLOVES:
199         if ((power != 0) || (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES)) {
200             GlovesEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
201         }
202
203         break;
204     case TV_RING:
205         if (!power && (randint0(100) < 50)) {
206             power = -1;
207         }
208
209         RingEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
210         break;
211     case TV_AMULET: {
212         if (!power && (randint0(100) < 50)) {
213             power = -1;
214         }
215
216         AmuletEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
217         break;
218     }
219     default: {
220         apply_magic_others(owner_ptr, o_ptr, power);
221         break;
222     }
223     }
224
225     if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (owner_ptr->pseikaku == PERSONALITY_SEXY)) {
226         o_ptr->pval = 3;
227         add_flag(o_ptr->art_flags, TR_STR);
228         add_flag(o_ptr->art_flags, TR_INT);
229         add_flag(o_ptr->art_flags, TR_WIS);
230         add_flag(o_ptr->art_flags, TR_DEX);
231         add_flag(o_ptr->art_flags, TR_CON);
232         add_flag(o_ptr->art_flags, TR_CHR);
233     }
234
235     if (object_is_ego(o_ptr)) {
236         apply_ego(owner_ptr, o_ptr, lev);
237         return;
238     }
239
240     if (o_ptr->k_idx) {
241         object_kind *k_ptr = &k_info[o_ptr->k_idx];
242         if (!k_info[o_ptr->k_idx].cost)
243             o_ptr->ident |= (IDENT_BROKEN);
244
245         if (k_ptr->gen_flags.has(TRG::CURSED))
246             o_ptr->curse_flags.set(TRC::CURSED);
247         if (k_ptr->gen_flags.has(TRG::HEAVY_CURSE))
248             o_ptr->curse_flags.set(TRC::HEAVY_CURSE);
249         if (k_ptr->gen_flags.has(TRG::PERMA_CURSE))
250             o_ptr->curse_flags.set(TRC::PERMA_CURSE);
251         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
252             o_ptr->curse_flags.set(get_curse(owner_ptr, 0, o_ptr));
253         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
254             o_ptr->curse_flags.set(get_curse(owner_ptr, 1, o_ptr));
255         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
256             o_ptr->curse_flags.set(get_curse(owner_ptr, 2, o_ptr));
257     }
258 }