OSDN Git Service

[Refactor] #933 Renamed accessory-enchanter-base.h to enchanter-base.h
[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-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-amulet.h"
14 #include "object-enchant/apply-magic-armor.h"
15 #include "object-enchant/apply-magic-others.h"
16 #include "object-enchant/apply-magic-ring.h"
17 #include "object-enchant/apply-magic-weapon.h"
18 #include "object-enchant/item-apply-magic.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-enchant.h"
26 #include "object/object-kind.h"
27 #include "player/player-status-flags.h"
28 #include "sv-definition/sv-armor-types.h"
29 #include "sv-definition/sv-protector-types.h"
30 #include "sv-definition/sv-weapon-types.h"
31 #include "system/artifact-type-definition.h"
32 #include "system/floor-type-definition.h"
33 #include "system/player-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  * @details
45  * エゴ&アーティファクトの生成、呪い、pval強化
46  */
47 void apply_magic_to_object(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 (has_good_luck(owner_ptr)) {
63         f1 += 5;
64         f2 += 2;
65     } else if (owner_ptr->muta.has(MUTA::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 (has_good_luck(owner_ptr) && 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 = apply_artifact(owner_ptr, o_ptr);
111         a_ptr->cur_num = 1;
112         if (current_world_ptr->character_dungeon)
113             a_ptr->floor_id = owner_ptr->floor_id;
114         return;
115     }
116
117     switch (o_ptr->tval) {
118     case TV_DIGGING:
119     case TV_HAFTED:
120     case TV_BOW:
121     case TV_SHOT:
122     case TV_ARROW:
123     case TV_BOLT: {
124         if (power)
125             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
126         break;
127     }
128     case TV_POLEARM: {
129         if (power && !(o_ptr->sval == SV_DEATH_SCYTHE))
130             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
131         break;
132     }
133     case TV_SWORD: {
134         if (power && !(o_ptr->sval == SV_POISON_NEEDLE))
135             apply_magic_weapon(owner_ptr, o_ptr, lev, power);
136         break;
137     }
138     case TV_DRAG_ARMOR:
139     case TV_HARD_ARMOR:
140     case TV_SOFT_ARMOR:
141     case TV_SHIELD:
142     case TV_HELM:
143     case TV_CROWN:
144     case TV_CLOAK:
145     case TV_GLOVES:
146     case TV_BOOTS: {
147         if (((o_ptr->tval == TV_CLOAK) && (o_ptr->sval == SV_ELVEN_CLOAK)) || ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_KUROSHOUZOKU)))
148             o_ptr->pval = randint1(4);
149
150         if (power || ((o_ptr->tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM)) || ((o_ptr->tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
151             || ((o_ptr->tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
152             || ((o_ptr->tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE)))
153             apply_magic_armor(owner_ptr, o_ptr, lev, power);
154
155         break;
156     }
157     case TV_RING:
158         if (!power && (randint0(100) < 50)) {
159             power = -1;
160         }
161
162         RingEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
163         break;
164     case TV_AMULET: {
165         if (!power && (randint0(100) < 50)) {
166             power = -1;
167         }
168
169         AmuletEnchanter(owner_ptr, o_ptr, lev, power).apply_magic();
170         break;
171     }
172     default: {
173         apply_magic_others(owner_ptr, o_ptr, power);
174         break;
175     }
176     }
177
178     if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (owner_ptr->pseikaku == PERSONALITY_SEXY)) {
179         o_ptr->pval = 3;
180         add_flag(o_ptr->art_flags, TR_STR);
181         add_flag(o_ptr->art_flags, TR_INT);
182         add_flag(o_ptr->art_flags, TR_WIS);
183         add_flag(o_ptr->art_flags, TR_DEX);
184         add_flag(o_ptr->art_flags, TR_CON);
185         add_flag(o_ptr->art_flags, TR_CHR);
186     }
187
188     if (object_is_ego(o_ptr)) {
189         apply_ego(owner_ptr, o_ptr, lev);
190         return;
191     }
192
193     if (o_ptr->k_idx) {
194         object_kind *k_ptr = &k_info[o_ptr->k_idx];
195         if (!k_info[o_ptr->k_idx].cost)
196             o_ptr->ident |= (IDENT_BROKEN);
197
198         if (k_ptr->gen_flags.has(TRG::CURSED))
199             o_ptr->curse_flags |= (TRC_CURSED);
200         if (k_ptr->gen_flags.has(TRG::HEAVY_CURSE))
201             o_ptr->curse_flags |= TRC_HEAVY_CURSE;
202         if (k_ptr->gen_flags.has(TRG::PERMA_CURSE))
203             o_ptr->curse_flags |= TRC_PERMA_CURSE;
204         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE0))
205             o_ptr->curse_flags |= get_curse(owner_ptr, 0, o_ptr);
206         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE1))
207             o_ptr->curse_flags |= get_curse(owner_ptr, 1, o_ptr);
208         if (k_ptr->gen_flags.has(TRG::RANDOM_CURSE2))
209             o_ptr->curse_flags |= get_curse(owner_ptr, 2, o_ptr);
210     }
211 }