OSDN Git Service

Merge pull request #1173 from Hourier/feature/Replace-Boolean-Macro
[hengbandforosx/hengbandosx.git] / src / object-enchant / apply-magic-armor.cpp
1 /*!
2  * @brief 防具系のアイテムを強化して(恐らく床に)生成する処理
3  * @date 2020/06/02
4  * @author Hourier
5  * @todo ちょっと長い。要分割
6  */
7
8 #include "object-enchant/apply-magic-armor.h"
9 #include "artifact/random-art-generator.h"
10 #include "inventory/inventory-slot-types.h"
11 #include "object-enchant/object-boost.h"
12 #include "object-enchant/object-ego.h"
13 #include "object/object-kind-hook.h"
14 #include "object/object-kind.h"
15 #include "object-enchant/tr-types.h"
16 #include "object-enchant/trc-types.h"
17 #include "sv-definition/sv-armor-types.h"
18 #include "sv-definition/sv-protector-types.h"
19 #include "system/object-type-definition.h"
20 #include "util/bit-flags-calculator.h"
21 #include "view/display-messages.h"
22
23 /*!
24  * @brief 防具系オブジェクトに生成ランクごとの強化を与えるサブルーチン
25  * Apply magic to an item known to be "armor"
26  * @param owner_ptr プレーヤーへの参照ポインタ
27  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
28  * @param level 生成基準階
29  * @param power 生成ランク
30  * @details
31  * Hack -- note special processing for crown/helm\n
32  * Hack -- note special processing for robe of permanence\n
33  */
34 void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level, int power)
35 {
36     ARMOUR_CLASS toac1 = (ARMOUR_CLASS)randint1(5) + m_bonus(5, level);
37     ARMOUR_CLASS toac2 = (ARMOUR_CLASS)m_bonus(10, level);
38     if (power > 0) {
39         o_ptr->to_a += toac1;
40         if (power > 1) {
41             o_ptr->to_a += toac2;
42         }
43     } else if (power < 0) {
44         o_ptr->to_a -= toac1;
45         if (power < -1) {
46             o_ptr->to_a -= toac2;
47         }
48
49         if (o_ptr->to_a < 0)
50             o_ptr->curse_flags.set(TRC::CURSED);
51     }
52
53     switch (o_ptr->tval) {
54     case TV_DRAG_ARMOR: {
55         /* power > 2 is debug only */
56         if (one_in_(50) || (power > 2))
57             become_random_artifact(owner_ptr, o_ptr, false);
58         break;
59     }
60     case TV_HARD_ARMOR:
61     case TV_SOFT_ARMOR: {
62         if (power > 1) {
63             if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ROBE) && (randint0(100) < 15)) {
64                 if (one_in_(5)) {
65                     o_ptr->name2 = EGO_YOIYAMI;
66                     o_ptr->k_idx = lookup_kind(TV_SOFT_ARMOR, SV_YOIYAMI_ROBE);
67                     o_ptr->sval = SV_YOIYAMI_ROBE;
68                     o_ptr->ac = 0;
69                     o_ptr->to_a = 0;
70                 } else {
71                     o_ptr->name2 = EGO_PERMANENCE;
72                 }
73
74                 break;
75             }
76
77             /* power > 2 is debug only */
78             if (one_in_(20) || (power > 2)) {
79                 become_random_artifact(owner_ptr, o_ptr, false);
80                 break;
81             }
82
83             while (true) {
84                 bool okay_flag = true;
85                 o_ptr->name2 = get_random_ego(INVEN_BODY, true);
86                 switch (o_ptr->name2) {
87                 case EGO_DWARVEN:
88                     if (o_ptr->tval != TV_HARD_ARMOR) {
89                         okay_flag = false;
90                     }
91
92                     break;
93                 case EGO_DRUID:
94                     if (o_ptr->tval != TV_SOFT_ARMOR) {
95                         okay_flag = false;
96                     }
97
98                     break;
99                 default:
100                     break;
101                 }
102
103                 if (okay_flag)
104                     break;
105             }
106         } else if (power < -1) {
107             while (true) {
108                 bool okay_flag = true;
109                 o_ptr->name2 = get_random_ego(INVEN_BODY, false);
110
111                 switch (o_ptr->name2) {
112                 case EGO_A_DEMON:
113                 case EGO_A_MORGUL:
114                     break;
115                 default:
116                     msg_print(_("エラー:適した呪い鎧エゴがみつかりませんでした.", "Error:Suitable cursed armor ego not found."));
117                     okay_flag = true;
118                     break;
119                 }
120
121                 if (okay_flag)
122                     break;
123             }
124         }
125
126         break;
127     }
128     case TV_SHIELD: {
129         if (o_ptr->sval == SV_DRAGON_SHIELD) {
130             dragon_resist(o_ptr);
131             if (!one_in_(3))
132                 break;
133         }
134
135         if (power > 1) {
136             /* power > 2 is debug only */
137             if (one_in_(20) || (power > 2)) {
138                 become_random_artifact(owner_ptr, o_ptr, false);
139                 break;
140             }
141
142             while (true) {
143                 o_ptr->name2 = get_random_ego(INVEN_SUB_HAND, true);
144                 if (o_ptr->sval != SV_SMALL_METAL_SHIELD && o_ptr->sval != SV_LARGE_METAL_SHIELD && o_ptr->name2 == EGO_S_DWARVEN) {
145                     continue;
146                 }
147
148                 break;
149             }
150
151             switch (o_ptr->name2) {
152             case EGO_REFLECTION:
153                 if (o_ptr->sval == SV_MIRROR_SHIELD)
154                     o_ptr->name2 = 0;
155                 break;
156             default:
157                 break;
158             }
159         }
160
161         break;
162     }
163     case TV_GLOVES: {
164         if (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES) {
165             dragon_resist(o_ptr);
166             if (!one_in_(3))
167                 break;
168         }
169
170         if (power > 1) {
171             /* power > 2 is debug only */
172             if (one_in_(20) || (power > 2)) {
173                 become_random_artifact(owner_ptr, o_ptr, false);
174                 break;
175             }
176             o_ptr->name2 = get_random_ego(INVEN_ARMS, true);
177         } else if (power < -1) {
178             o_ptr->name2 = get_random_ego(INVEN_ARMS, false);
179         }
180
181         break;
182     }
183
184     case TV_BOOTS: {
185         if (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE) {
186             dragon_resist(o_ptr);
187             if (!one_in_(3))
188                 break;
189         }
190
191         if (power > 1) {
192             /* power > 2 is debug only */
193             if (one_in_(20) || (power > 2)) {
194                 become_random_artifact(owner_ptr, o_ptr, false);
195                 break;
196             }
197
198             o_ptr->name2 = get_random_ego(INVEN_FEET, true);
199         } else if (power < -1) {
200             o_ptr->name2 = get_random_ego(INVEN_FEET, false);
201         }
202
203         break;
204     }
205     case TV_CROWN: {
206         if (power > 1) {
207             /* power > 2 is debug only */
208             if (one_in_(20) || (power > 2)) {
209                 become_random_artifact(owner_ptr, o_ptr, false);
210                 break;
211             }
212
213             while (true) {
214                 bool ok_flag = true;
215                 o_ptr->name2 = get_random_ego(INVEN_HEAD, true);
216
217                 switch (o_ptr->name2) {
218                 case EGO_TELEPATHY:
219                 case EGO_MAGI:
220                 case EGO_MIGHT:
221                 case EGO_REGENERATION:
222                 case EGO_LORDLINESS:
223                 case EGO_BASILISK:
224                     break;
225                 case EGO_SEEING:
226                     if (one_in_(3))
227                         add_low_telepathy(o_ptr);
228                     break;
229                 default:
230                     /* not existing crown (wisdom,lite, etc...) */
231                     ok_flag = false;
232                 }
233
234                 if (ok_flag)
235                     break;
236             }
237
238             break;
239         } else if (power < -1) {
240             while (true) {
241                 bool ok_flag = true;
242                 o_ptr->name2 = get_random_ego(INVEN_HEAD, false);
243
244                 switch (o_ptr->name2) {
245                 case EGO_H_DEMON:
246                     ok_flag = false;
247                     break;
248                 default:
249                     break;
250                 }
251
252                 if (ok_flag)
253                     break;
254             }
255         }
256
257         break;
258     }
259     case TV_HELM: {
260         if (o_ptr->sval == SV_DRAGON_HELM) {
261             dragon_resist(o_ptr);
262             if (!one_in_(3))
263                 break;
264         }
265
266         if (power > 1) {
267             /* power > 2 is debug only */
268             if (one_in_(20) || (power > 2)) {
269                 become_random_artifact(owner_ptr, o_ptr, false);
270                 break;
271             }
272
273             while (true) {
274                 bool ok_flag = true;
275                 o_ptr->name2 = get_random_ego(INVEN_HEAD, true);
276                 switch (o_ptr->name2) {
277                 case EGO_BRILLIANCE:
278                 case EGO_DARK:  
279                 case EGO_INFRAVISION:
280                 case EGO_H_PROTECTION:
281                 case EGO_LITE:
282                     break;
283                 case EGO_SEEING:
284                     if (one_in_(7))
285                         add_low_telepathy(o_ptr);
286                     break;
287                 default:
288                     /* not existing helm (Magi, Might, etc...)*/
289                     ok_flag = false;
290                 }
291
292                 if (ok_flag)
293                     break;
294             }
295
296             break;
297         } else if (power < -1) {
298             while (true) {
299                 bool ok_flag = true;
300                 o_ptr->name2 = get_random_ego(INVEN_HEAD, false);
301
302                 switch (o_ptr->name2) {
303                 case EGO_ANCIENT_CURSE:
304                     ok_flag = false;
305                     break;
306                 default:
307                     break;
308                 }
309
310                 if (ok_flag)
311                     break;
312             }
313         }
314
315         break;
316     }
317     case TV_CLOAK: {
318         if (power > 1) {
319             /* power > 2 is debug only */
320             if (one_in_(20) || (power > 2)) {
321                 become_random_artifact(owner_ptr, o_ptr, false);
322                 break;
323             }
324             o_ptr->name2 = get_random_ego(INVEN_OUTER, true);
325         } else if (power < -1) {
326             o_ptr->name2 = get_random_ego(INVEN_OUTER, false);
327         }
328
329         break;
330     }
331
332     default:
333         break;
334     }
335 }