OSDN Git Service

Merge pull request #2122 from sikabane-works/release/3.0.0Alpha52
[hengbandforosx/hengbandosx.git] / src / object-enchant / weapon / apply-magic-weapon.cpp
1 /*!
2  * @brief 武器系のアイテムを強化する処理
3  * @date 2022/01/30
4  * @author Hourier
5  */
6
7 #include "object-enchant/weapon/apply-magic-weapon.h"
8 #include "artifact/random-art-generator.h"
9 #include "inventory/inventory-slot-types.h"
10 #include "object-enchant/object-boost.h"
11 #include "object-enchant/object-ego.h"
12 #include "object-enchant/tr-types.h"
13 #include "object-enchant/trc-types.h"
14 #include "sv-definition/sv-weapon-types.h"
15 #include "system/floor-type-definition.h"
16 #include "system/object-type-definition.h"
17 #include "util/bit-flags-calculator.h"
18 #include "view/display-messages.h"
19
20 /*!
21  * @brief 武器強化クラスのコンストラクタ
22  * @param player_ptr プレイヤーへの参照ポインタ
23  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
24  * @param level 生成基準階
25  * @param power 生成ランク
26  */
27 WeaponEnchanter::WeaponEnchanter(PlayerType *player_ptr, object_type *o_ptr, DEPTH level, int power)
28     : AbstractWeaponEnchanter(o_ptr, level, power)
29     , player_ptr(player_ptr)
30 {
31 }
32
33 /*!
34  * @brief 武器系オブジェクトに生成ランクごとの強化を与えるサブルーチン
35  * Apply magic to an item known to be a "weapon"
36  */
37 void WeaponEnchanter::apply_magic()
38 {
39     if ((this->o_ptr->tval == ItemKindType::SWORD) && (this->o_ptr->sval == SV_DIAMOND_EDGE))
40         return;
41
42     switch (this->o_ptr->tval) {
43     case ItemKindType::DIGGING: {
44         if (this->power > 1) {
45             /* this->power > 2はデバッグ専用. */
46             if (one_in_(30) || (this->power > 2))
47                 become_random_artifact(this->player_ptr, this->o_ptr, false);
48             else
49                 this->o_ptr->name2 = EGO_DIGGING;
50         } else if (this->power < -1) {
51             this->o_ptr->pval = 0 - (5 + randint1(5));
52         } else if (this->power < 0) {
53             this->o_ptr->pval = 0 - (this->o_ptr->pval);
54         }
55
56         break;
57     }
58     case ItemKindType::HAFTED:
59     case ItemKindType::POLEARM:
60     case ItemKindType::SWORD: {
61         if (this->power > 1) {
62             /* power > 2はデバッグ専用. */
63             if (one_in_(40) || (this->power > 2)) {
64                 become_random_artifact(this->player_ptr, this->o_ptr, false);
65                 break;
66             }
67             while (true) {
68                 this->o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, true);
69                 if (this->o_ptr->name2 == EGO_SHARPNESS && this->o_ptr->tval != ItemKindType::SWORD)
70                     continue;
71                 if (this->o_ptr->name2 == EGO_EARTHQUAKES && this->o_ptr->tval != ItemKindType::HAFTED)
72                     continue;
73                 break;
74             }
75
76             switch (this->o_ptr->name2) {
77             case EGO_SHARPNESS:
78                 this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, this->level) + 1;
79                 break;
80             case EGO_EARTHQUAKES:
81                 if (one_in_(3) && (this->level > 60))
82                     this->o_ptr->art_flags.set(TR_BLOWS);
83                 else
84                     this->o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, this->level);
85                 break;
86             default:
87                 break;
88             }
89
90             if (!this->o_ptr->art_name) {
91                 while (one_in_(10L * this->o_ptr->dd * this->o_ptr->ds))
92                     this->o_ptr->dd++;
93
94                 if (this->o_ptr->dd > 9)
95                     this->o_ptr->dd = 9;
96             }
97         } else if (this->power < -1) {
98             if (randint0(MAX_DEPTH) < this->level) {
99                 int n = 0;
100                 while (true) {
101                     this->o_ptr->name2 = get_random_ego(INVEN_MAIN_HAND, false);
102                     if (this->o_ptr->name2 == EGO_WEIRD && this->o_ptr->tval != ItemKindType::SWORD) {
103                         continue;
104                     }
105
106                     ego_item_type *e_ptr = &e_info[this->o_ptr->name2];
107                     if (this->o_ptr->tval == ItemKindType::SWORD && this->o_ptr->sval == SV_HAYABUSA && e_ptr->max_pval < 0) {
108                         if (++n > 1000) {
109                             msg_print(_("エラー:隼の剣に割り当てるエゴ無し", "Error: Cannot find for Hayabusa."));
110                             return;
111                         }
112                         continue;
113                     }
114                     break;
115                 }
116             }
117         }
118
119         break;
120     }
121     case ItemKindType::BOW: {
122         if (this->power > 1) {
123             /* this->power > 2はデバッグ専用. */
124             if (one_in_(20) || (this->power > 2)) {
125                 become_random_artifact(this->player_ptr, this->o_ptr, false);
126                 break;
127             }
128
129             this->o_ptr->name2 = get_random_ego(INVEN_BOW, true);
130         }
131
132         break;
133     }
134     case ItemKindType::BOLT:
135     case ItemKindType::ARROW:
136     case ItemKindType::SHOT: {
137         if (this->power > 1) {
138             /* this->power > 2はデバッグ専用. */
139             if (this->power > 2) {
140                 become_random_artifact(this->player_ptr, this->o_ptr, false);
141                 break;
142             }
143
144             this->o_ptr->name2 = get_random_ego(INVEN_AMMO, true);
145
146             while (one_in_(10L * this->o_ptr->dd * this->o_ptr->ds))
147                 this->o_ptr->dd++;
148
149             if (this->o_ptr->dd > 9)
150                 this->o_ptr->dd = 9;
151         } else if (this->power < -1) {
152             if (randint0(MAX_DEPTH) < this->level) {
153                 this->o_ptr->name2 = get_random_ego(INVEN_AMMO, false);
154             }
155         }
156
157         break;
158     }
159
160     default:
161         break;
162     }
163 }