OSDN Git Service

Merge pull request #481 from iks3/fix-equip-water-and-time
[hengbandforosx/hengbandosx.git] / src / object-enchant / apply-magic-armor.cpp
1 /*!
2  * todo ちょっと長い。要分割
3  * @brief 防具系のアイテムを強化して(恐らく床に)生成する処理
4  * @date 2020/06/02
5  * @author Hourier
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 "util/bit-flags-calculator.h"
20
21 /*!
22  * @brief 防具系オブジェクトに生成ランクごとの強化を与えるサブルーチン
23  * Apply magic to an item known to be "armor"
24  * @param owner_ptr プレーヤーへの参照ポインタ
25  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
26  * @param level 生成基準階
27  * @param power 生成ランク
28  * @return なし
29  * @details
30  * Hack -- note special processing for crown/helm\n
31  * Hack -- note special processing for robe of permanence\n
32  */
33 void apply_magic_armor(player_type *owner_ptr, object_type *o_ptr, DEPTH level, int power)
34 {
35     ARMOUR_CLASS toac1 = (ARMOUR_CLASS)randint1(5) + m_bonus(5, level);
36     ARMOUR_CLASS toac2 = (ARMOUR_CLASS)m_bonus(10, level);
37     if (power > 0) {
38         o_ptr->to_a += toac1;
39         if (power > 1) {
40             o_ptr->to_a += toac2;
41         }
42     } else if (power < 0) {
43         o_ptr->to_a -= toac1;
44         if (power < -1) {
45             o_ptr->to_a -= toac2;
46         }
47
48         if (o_ptr->to_a < 0)
49             o_ptr->curse_flags |= TRC_CURSED;
50     }
51
52     switch (o_ptr->tval) {
53     case TV_DRAG_ARMOR: {
54         /* power > 2 is debug only */
55         if (one_in_(50) || (power > 2))
56             become_random_artifact(owner_ptr, o_ptr, FALSE);
57         break;
58     }
59     case TV_HARD_ARMOR:
60     case TV_SOFT_ARMOR: {
61         if (power > 1) {
62             if ((o_ptr->tval == TV_SOFT_ARMOR) && (o_ptr->sval == SV_ROBE) && (randint0(100) < 15)) {
63                 if (one_in_(5)) {
64                     o_ptr->name2 = EGO_YOIYAMI;
65                     o_ptr->k_idx = lookup_kind(TV_SOFT_ARMOR, SV_YOIYAMI_ROBE);
66                     o_ptr->sval = SV_YOIYAMI_ROBE;
67                     o_ptr->ac = 0;
68                     o_ptr->to_a = 0;
69                 } else {
70                     o_ptr->name2 = EGO_PERMANENCE;
71                 }
72
73                 break;
74             }
75
76             /* power > 2 is debug only */
77             if (one_in_(20) || (power > 2)) {
78                 become_random_artifact(owner_ptr, o_ptr, FALSE);
79                 break;
80             }
81
82             while (TRUE) {
83                 bool okay_flag = TRUE;
84                 o_ptr->name2 = get_random_ego(INVEN_BODY, TRUE);
85                 switch (o_ptr->name2) {
86                 case EGO_DWARVEN:
87                     if (o_ptr->tval != TV_HARD_ARMOR) {
88                         okay_flag = FALSE;
89                     }
90
91                     break;
92                 case EGO_DRUID:
93                     if (o_ptr->tval != TV_SOFT_ARMOR) {
94                         okay_flag = FALSE;
95                     }
96
97                     break;
98                 default:
99                     break;
100                 }
101
102                 if (okay_flag)
103                     break;
104             }
105
106             switch (o_ptr->name2) {
107             case EGO_RESISTANCE:
108                 if (one_in_(4))
109                     add_flag(o_ptr->art_flags, TR_RES_POIS);
110                 break;
111             case EGO_DWARVEN:
112                 o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
113                 o_ptr->ac = k_info[o_ptr->k_idx].ac + 5;
114                 break;
115             default:
116                 break;
117             }
118         } else if (power < -1) {
119             while (TRUE) {
120                 bool okay_flag = TRUE;
121                 o_ptr->name2 = get_random_ego(INVEN_BODY, FALSE);
122
123                 switch (o_ptr->name2) {
124                 case EGO_A_DEMON:
125                     if (one_in_(3))
126                         o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
127                     one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
128                                : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
129
130                     if (one_in_(3))
131                         add_flag(o_ptr->art_flags, TR_AGGRAVATE);
132                     if (one_in_(3))
133                         add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
134                     if (one_in_(5))
135                         add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
136                     if (one_in_(5))
137                         add_flag(o_ptr->art_flags, TR_DRAIN_HP);
138                     if (one_in_(5))
139                         add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
140                     if (one_in_(5))
141                         add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
142                     if (one_in_(5))
143                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
144                     if (one_in_(5))
145                         add_flag(o_ptr->art_flags, TR_CALL_DEMON);
146                     break;
147                 case EGO_A_MORGUL:
148                     if (one_in_(3))
149                         o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
150                     if (one_in_(9))
151                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
152                     if (one_in_(4))
153                         add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
154                     if (one_in_(6))
155                         add_flag(o_ptr->art_flags, TR_AGGRAVATE);
156                     if (one_in_(9))
157                         add_flag(o_ptr->art_flags, TR_NO_MAGIC);
158                     if (one_in_(9))
159                         add_flag(o_ptr->art_flags, TR_NO_TELE);
160                     break;
161                 default:
162                     okay_flag = false;
163                     break;
164                 }
165
166                 if (okay_flag)
167                     break;
168             }
169         }
170
171         break;
172     }
173     case TV_SHIELD: {
174         if (o_ptr->sval == SV_DRAGON_SHIELD) {
175             dragon_resist(o_ptr);
176             if (!one_in_(3))
177                 break;
178         }
179
180         if (power > 1) {
181             /* power > 2 is debug only */
182             if (one_in_(20) || (power > 2)) {
183                 become_random_artifact(owner_ptr, o_ptr, FALSE);
184                 break;
185             }
186
187             while (TRUE) {
188                 o_ptr->name2 = get_random_ego(INVEN_SUB_HAND, TRUE);
189                 if (o_ptr->sval != SV_SMALL_METAL_SHIELD && o_ptr->sval != SV_LARGE_METAL_SHIELD && o_ptr->name2 == EGO_S_DWARVEN) {
190                     continue;
191                 }
192
193                 break;
194             }
195
196             switch (o_ptr->name2) {
197             case EGO_ENDURANCE:
198                 if (!one_in_(3))
199                     one_high_resistance(o_ptr);
200                 if (one_in_(4))
201                     add_flag(o_ptr->art_flags, TR_RES_POIS);
202                 break;
203             case EGO_REFLECTION:
204                 if (o_ptr->sval == SV_MIRROR_SHIELD)
205                     o_ptr->name2 = 0;
206                 break;
207
208             case EGO_S_DWARVEN:
209                 o_ptr->weight = (2 * k_info[o_ptr->k_idx].weight / 3);
210                 o_ptr->ac = k_info[o_ptr->k_idx].ac + 3;
211                 break;
212             }
213         }
214
215         break;
216     }
217     case TV_GLOVES: {
218         if (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES) {
219             dragon_resist(o_ptr);
220             if (!one_in_(3))
221                 break;
222         }
223
224         if (power > 1) {
225             /* power > 2 is debug only */
226             if (one_in_(20) || (power > 2)) {
227                 become_random_artifact(owner_ptr, o_ptr, FALSE);
228                 break;
229             }
230             o_ptr->name2 = get_random_ego(INVEN_ARMS, TRUE);
231         } else if (power < -1) {
232             o_ptr->name2 = get_random_ego(INVEN_ARMS, FALSE);
233         }
234
235         break;
236     }
237
238     case TV_BOOTS: {
239         if (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE) {
240             dragon_resist(o_ptr);
241             if (!one_in_(3))
242                 break;
243         }
244
245         if (power > 1) {
246             /* power > 2 is debug only */
247             if (one_in_(20) || (power > 2)) {
248                 become_random_artifact(owner_ptr, o_ptr, FALSE);
249                 break;
250             }
251
252             o_ptr->name2 = get_random_ego(INVEN_FEET, TRUE);
253             switch (o_ptr->name2) {
254             case EGO_SLOW_DESCENT:
255                 if (one_in_(2)) {
256                     one_high_resistance(o_ptr);
257                 }
258
259                 break;
260             }
261         } else if (power < -1) {
262             o_ptr->name2 = get_random_ego(INVEN_FEET, FALSE);
263         }
264
265         break;
266     }
267     case TV_CROWN: {
268         if (power > 1) {
269             /* power > 2 is debug only */
270             if (one_in_(20) || (power > 2)) {
271                 become_random_artifact(owner_ptr, o_ptr, FALSE);
272                 break;
273             }
274
275             while (TRUE) {
276                 bool ok_flag = TRUE;
277                 o_ptr->name2 = get_random_ego(INVEN_HEAD, TRUE);
278
279                 switch (o_ptr->name2) {
280                 case EGO_TELEPATHY:
281                     if (add_esp_strong(o_ptr))
282                         add_esp_weak(o_ptr, TRUE);
283                     else
284                         add_esp_weak(o_ptr, FALSE);
285                     break;
286                 case EGO_MAGI:
287                 case EGO_MIGHT:
288                 case EGO_REGENERATION:
289                 case EGO_LORDLINESS:
290                 case EGO_BASILISK:
291                     break;
292                 case EGO_SEEING:
293                     if (one_in_(3)) {
294                         if (one_in_(2))
295                             add_esp_strong(o_ptr);
296                         else
297                             add_esp_weak(o_ptr, FALSE);
298                     }
299                     break;
300                 default:
301                     /* not existing crown (wisdom,lite, etc...) */
302                     ok_flag = FALSE;
303                 }
304
305                 if (ok_flag)
306                     break;
307             }
308
309             break;
310         } else if (power < -1) {
311             while (TRUE) {
312                 bool ok_flag = TRUE;
313                 o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
314
315                 switch (o_ptr->name2) {
316                 case EGO_H_DEMON:
317                     ok_flag = false;
318                     break;
319                 case EGO_ANCIENT_CURSE:
320                     if (one_in_(3))
321                         add_flag(o_ptr->art_flags, TR_NO_MAGIC);
322                     if (one_in_(3))
323                         add_flag(o_ptr->art_flags, TR_NO_TELE);
324                     if (one_in_(3))
325                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
326                     if (one_in_(3))
327                         add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
328                     if (one_in_(3))
329                         add_flag(o_ptr->art_flags, TR_DRAIN_HP);
330                     if (one_in_(3))
331                         add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
332                     break;
333                 }
334
335                 if (ok_flag)
336                     break;
337             }
338         }
339
340         break;
341     }
342     case TV_HELM: {
343         if (o_ptr->sval == SV_DRAGON_HELM) {
344             dragon_resist(o_ptr);
345             if (!one_in_(3))
346                 break;
347         }
348
349         if (power > 1) {
350             /* power > 2 is debug only */
351             if (one_in_(20) || (power > 2)) {
352                 become_random_artifact(owner_ptr, o_ptr, FALSE);
353                 break;
354             }
355
356             while (TRUE) {
357                 bool ok_flag = TRUE;
358                 o_ptr->name2 = get_random_ego(INVEN_HEAD, TRUE);
359                 switch (o_ptr->name2) {
360                 case EGO_BRILLIANCE:
361                 case EGO_DARK:
362                 case EGO_INFRAVISION:
363                 case EGO_H_PROTECTION:
364                     break;
365                 case EGO_SEEING:
366                     if (one_in_(7)) {
367                         if (one_in_(2))
368                             add_esp_strong(o_ptr);
369                         else
370                             add_esp_weak(o_ptr, FALSE);
371                     }
372
373                     break;
374                 case EGO_LITE:
375                     if (one_in_(3))
376                         add_flag(o_ptr->art_flags, TR_LITE_1);
377                     if (one_in_(3))
378                         add_flag(o_ptr->art_flags, TR_LITE_2);
379                     break;
380                 default:
381                     /* not existing helm (Magi, Might, etc...)*/
382                     ok_flag = FALSE;
383                 }
384
385                 if (ok_flag)
386                     break;
387             }
388
389             break;
390         } else if (power < -1) {
391             while (TRUE) {
392                 bool ok_flag = TRUE;
393                 o_ptr->name2 = get_random_ego(INVEN_HEAD, FALSE);
394
395                 switch (o_ptr->name2) {
396                 case EGO_H_DEMON:
397                     if (one_in_(3))
398                         o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
399                     one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
400                                : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
401
402                     if (one_in_(3))
403                         add_flag(o_ptr->art_flags, TR_AGGRAVATE);
404                     if (one_in_(3))
405                         add_flag(o_ptr->art_flags, TR_ADD_L_CURSE);
406                     if (one_in_(5))
407                         add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
408                     if (one_in_(5))
409                         add_flag(o_ptr->art_flags, TR_DRAIN_HP);
410                     if (one_in_(5))
411                         add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
412                     if (one_in_(5))
413                         add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
414                     if (one_in_(5))
415                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
416                     if (one_in_(5))
417                         add_flag(o_ptr->art_flags, TR_CALL_DEMON);
418                     break;
419                 case EGO_ANCIENT_CURSE:
420                     ok_flag = FALSE;
421                     break;
422                 }
423
424                 if (ok_flag)
425                     break;
426             }
427         }
428
429         break;
430     }
431     case TV_CLOAK: {
432         if (power > 1) {
433             /* power > 2 is debug only */
434             if (one_in_(20) || (power > 2)) {
435                 become_random_artifact(owner_ptr, o_ptr, FALSE);
436                 break;
437             }
438             o_ptr->name2 = get_random_ego(INVEN_OUTER, TRUE);
439
440             switch (o_ptr->name2) {
441             case EGO_BAT:
442                 o_ptr->to_d -= 6;
443                 o_ptr->to_h -= 6;
444                 break;
445             case EGO_NAZGUL:
446                 o_ptr->to_d -= 3;
447                 o_ptr->to_h -= 3;
448                 if (one_in_(3))
449                     add_flag(o_ptr->art_flags, TR_COWARDICE);
450                 if (one_in_(3))
451                     add_flag(o_ptr->art_flags, TR_CALL_UNDEAD);
452                 if (one_in_(3))
453                     add_flag(o_ptr->art_flags, TR_SLOW_REGEN);
454                 if (one_in_(3))
455                     add_flag(o_ptr->art_flags, TR_DRAIN_EXP);
456                 break;
457             }
458
459         } else if (power < -1) {
460             o_ptr->name2 = get_random_ego(INVEN_OUTER, FALSE);
461         }
462
463         break;
464     }
465     }
466 }