OSDN Git Service

[Refactor] enum classの型名変更 TRG -> ItemGenerationTraitType
[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/object-kind.h"
32 #include "player/player-status-flags.h"
33 #include "sv-definition/sv-armor-types.h"
34 #include "sv-definition/sv-protector-types.h"
35 #include "sv-definition/sv-weapon-types.h"
36 #include "system/artifact-type-definition.h"
37 #include "system/floor-type-definition.h"
38 #include "system/player-type-definition.h"
39 #include "util/bit-flags-calculator.h"
40 #include "world/world.h"
41
42 /*!
43  * @brief 生成されたベースアイテムに魔法的な強化を与えるメインルーチン
44  * Complete the "creation" of an object by applying "magic" to the item
45  * @param player_ptr プレイヤーへの参照ポインタ
46  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
47  * @param lev 生成基準階
48  * @param mode 生成オプション
49  * @details
50  * エゴ&アーティファクトの生成、呪い、pval強化
51  */
52 void apply_magic_to_object(player_type *player_ptr, object_type *o_ptr, DEPTH lev, BIT_FLAGS mode)
53 {
54     if (player_ptr->ppersonality == PERSONALITY_MUNCHKIN)
55         lev += randint0(player_ptr->lev / 2 + 10);
56     if (lev > MAX_DEPTH - 1)
57         lev = MAX_DEPTH - 1;
58
59     int f1 = lev + 10;
60     if (f1 > d_info[player_ptr->dungeon_idx].obj_good)
61         f1 = d_info[player_ptr->dungeon_idx].obj_good;
62
63     int f2 = f1 * 2 / 3;
64     if ((player_ptr->ppersonality != PERSONALITY_MUNCHKIN) && (f2 > d_info[player_ptr->dungeon_idx].obj_great))
65         f2 = d_info[player_ptr->dungeon_idx].obj_great;
66
67     if (has_good_luck(player_ptr)) {
68         f1 += 5;
69         f2 += 2;
70     } else if (player_ptr->muta.has(PlayerMutationType::BAD_LUCK)) {
71         f1 -= 5;
72         f2 -= 2;
73     }
74
75     int power = 0;
76     if ((mode & AM_GOOD) || magik(f1)) {
77         power = 1;
78         if ((mode & AM_GREAT) || magik(f2)) {
79             power = 2;
80             if (mode & AM_SPECIAL)
81                 power = 3;
82         }
83     } else if (magik(f1)) {
84         power = -1;
85         if (magik(f2))
86             power = -2;
87     }
88     if (mode & AM_CURSED) {
89         if (power > 0) {
90             power = 0 - power;
91         } else {
92             power--;
93         }
94     }
95
96     int rolls = 0;
97     if (power >= 2)
98         rolls = 1;
99
100     if (mode & (AM_GREAT | AM_SPECIAL))
101         rolls = 4;
102     if ((mode & AM_NO_FIXED_ART) || o_ptr->name1)
103         rolls = 0;
104
105     for (int i = 0; i < rolls; i++) {
106         if (make_artifact(player_ptr, o_ptr))
107             break;
108         if (has_good_luck(player_ptr) && one_in_(77)) {
109             if (make_artifact(player_ptr, o_ptr))
110                 break;
111         }
112     }
113
114     if (o_ptr->is_fixed_artifact()) {
115         artifact_type *a_ptr = apply_artifact(player_ptr, o_ptr);
116         a_ptr->cur_num = 1;
117         if (w_ptr->character_dungeon)
118             a_ptr->floor_id = player_ptr->floor_id;
119         return;
120     }
121
122     switch (o_ptr->tval) {
123     case ItemKindType::DIGGING:
124     case ItemKindType::HAFTED:
125     case ItemKindType::BOW:
126     case ItemKindType::SHOT:
127     case ItemKindType::ARROW:
128     case ItemKindType::BOLT:
129         if (power != 0) {
130             apply_magic_weapon(player_ptr, o_ptr, lev, power);
131         }
132
133         break;
134     case ItemKindType::POLEARM:
135         if ((power != 0) && (o_ptr->sval != SV_DEATH_SCYTHE)) {
136             apply_magic_weapon(player_ptr, o_ptr, lev, power);
137         }
138
139         break;
140     case ItemKindType::SWORD:
141         if ((power != 0) && (o_ptr->sval != SV_POISON_NEEDLE)) {
142             apply_magic_weapon(player_ptr, o_ptr, lev, power);
143         }
144
145         break;
146     case ItemKindType::SHIELD:
147         ShieldEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
148         break;
149     case ItemKindType::CLOAK:
150         CloakEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
151         break;
152     case ItemKindType::HELM:
153         HelmEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
154         break;
155     case ItemKindType::CROWN:
156         CrownEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
157         break;
158     case ItemKindType::BOOTS:
159         BootsEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
160         break;
161     case ItemKindType::DRAG_ARMOR:
162     case ItemKindType::HARD_ARMOR:
163     case ItemKindType::SOFT_ARMOR:
164         ArmorEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
165         break;
166     case ItemKindType::GLOVES:
167         GlovesEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
168         break;
169     case ItemKindType::RING:
170         RingEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
171         break;
172     case ItemKindType::AMULET:
173         AmuletEnchanter(player_ptr, o_ptr, lev, power).apply_magic();
174         break;
175     default:
176         apply_magic_others(player_ptr, o_ptr, power);
177         break;
178     }
179
180     if ((o_ptr->tval == ItemKindType::SOFT_ARMOR) && (o_ptr->sval == SV_ABUNAI_MIZUGI) && (player_ptr->ppersonality == PERSONALITY_SEXY)) {
181         o_ptr->pval = 3;
182         o_ptr->art_flags.set(TR_STR);
183         o_ptr->art_flags.set(TR_INT);
184         o_ptr->art_flags.set(TR_WIS);
185         o_ptr->art_flags.set(TR_DEX);
186         o_ptr->art_flags.set(TR_CON);
187         o_ptr->art_flags.set(TR_CHR);
188     }
189
190     if (o_ptr->is_ego()) {
191         apply_ego(o_ptr, lev);
192         return;
193     }
194
195     if (o_ptr->k_idx) {
196         object_kind *k_ptr = &k_info[o_ptr->k_idx];
197         if (!k_info[o_ptr->k_idx].cost)
198             o_ptr->ident |= (IDENT_BROKEN);
199
200         if (k_ptr->gen_flags.has(ItemGenerationTraitType::CURSED))
201             o_ptr->curse_flags.set(CurseTraitType::CURSED);
202         if (k_ptr->gen_flags.has(ItemGenerationTraitType::HEAVY_CURSE))
203             o_ptr->curse_flags.set(CurseTraitType::HEAVY_CURSE);
204         if (k_ptr->gen_flags.has(ItemGenerationTraitType::PERMA_CURSE))
205             o_ptr->curse_flags.set(CurseTraitType::PERMA_CURSE);
206         if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE0))
207             o_ptr->curse_flags.set(get_curse(0, o_ptr));
208         if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE1))
209             o_ptr->curse_flags.set(get_curse(1, o_ptr));
210         if (k_ptr->gen_flags.has(ItemGenerationTraitType::RANDOM_CURSE2))
211             o_ptr->curse_flags.set(get_curse(2, o_ptr));
212     }
213 }