OSDN Git Service

[Refactor] #40521 Separated inventory-slot-types.h from player-status.h
[hengband/hengband.git] / src / object-enchant / apply-magic-weapon.c
1 /*!
2  * todo ちょっと長い。要分割
3  * @brief 武器系のアイテムを強化して(恐らく床に)生成する処理
4  * @date 2020/06/02
5  * @author Hourier
6  */
7
8 #include "object-enchant/apply-magic-weapon.h"
9 #include "floor/floor.h"
10 #include "inventory/inventory-slot-types.h"
11 #include "object-enchant/artifact.h"
12 #include "object-enchant/object-boost.h"
13 #include "object-enchant/object-ego.h"
14 #include "object-enchant/tr-types.h"
15 #include "object-enchant/trc-types.h"
16 #include "sv-definition/sv-weapon-types.h"
17 #include "util/bit-flags-calculator.h"
18
19 /*!
20  * @brief 武器系オブジェクトに生成ランクごとの強化を与えるサブルーチン
21  * Apply magic to an item known to be a "weapon"
22  * @param owner_ptr プレーヤーへの参照ポインタ
23  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
24  * @param level 生成基準階
25  * @param power 生成ランク
26  * @return なし
27  * @details
28  * Hack -- note special base damage dice boosting\n
29  * Hack -- note special processing for weapon/digger\n
30  */
31 void apply_magic_weapon(player_type *owner_ptr, object_type *o_ptr, DEPTH level, int power)
32 {
33     HIT_PROB tohit1 = randint1(5) + (HIT_PROB)m_bonus(5, level);
34     HIT_POINT todam1 = randint1(5) + (HIT_POINT)m_bonus(5, level);
35
36     HIT_PROB tohit2 = (HIT_PROB)m_bonus(10, level);
37     HIT_POINT todam2 = (HIT_POINT)m_bonus(10, level);
38
39     if ((o_ptr->tval == TV_BOLT) || (o_ptr->tval == TV_ARROW) || (o_ptr->tval == TV_SHOT)) {
40         tohit2 = (tohit2 + 1) / 2;
41         todam2 = (todam2 + 1) / 2;
42     }
43
44     if (power > 0) {
45         o_ptr->to_h += tohit1;
46         o_ptr->to_d += todam1;
47         if (power > 1) {
48             o_ptr->to_h += tohit2;
49             o_ptr->to_d += todam2;
50         }
51     } else if (power < 0) {
52         o_ptr->to_h -= tohit1;
53         o_ptr->to_d -= todam1;
54         if (power < -1) {
55             o_ptr->to_h -= tohit2;
56             o_ptr->to_d -= todam2;
57         }
58
59         if (o_ptr->to_h + o_ptr->to_d < 0)
60             o_ptr->curse_flags |= TRC_CURSED;
61     }
62
63     if ((o_ptr->tval == TV_SWORD) && (o_ptr->sval == SV_DIAMOND_EDGE))
64         return;
65
66     switch (o_ptr->tval) {
67     case TV_DIGGING: {
68         if (power > 1) {
69             /* power > 2 is debug only */
70             if (one_in_(30) || (power > 2))
71                 become_random_artifact(owner_ptr, o_ptr, FALSE);
72             else
73                 o_ptr->name2 = EGO_DIGGING;
74         } else if (power < -1) {
75             o_ptr->pval = 0 - (5 + randint1(5));
76         } else if (power < 0) {
77             o_ptr->pval = 0 - (o_ptr->pval);
78         }
79
80         break;
81     }
82     case TV_HAFTED:
83     case TV_POLEARM:
84     case TV_SWORD: {
85         if (power > 1) {
86             /* power > 2 is debug only */
87             if (one_in_(40) || (power > 2)) {
88                 become_random_artifact(owner_ptr, o_ptr, FALSE);
89                 break;
90             }
91             while (TRUE) {
92                 o_ptr->name2 = get_random_ego(INVEN_RARM, TRUE);
93                 if (o_ptr->name2 == EGO_SHARPNESS && o_ptr->tval != TV_SWORD)
94                     continue;
95                 if (o_ptr->name2 == EGO_EARTHQUAKES && o_ptr->tval != TV_HAFTED)
96                     continue;
97                 if (o_ptr->name2 == EGO_WEIRD && o_ptr->tval != TV_SWORD)
98                     continue;
99                 break;
100             }
101
102             switch (o_ptr->name2) {
103             case EGO_HA:
104                 if (one_in_(4) && (level > 40))
105                     add_flag(o_ptr->art_flags, TR_BLOWS);
106                 break;
107             case EGO_DF:
108                 if (one_in_(3))
109                     add_flag(o_ptr->art_flags, TR_RES_POIS);
110                 if (one_in_(3))
111                     add_flag(o_ptr->art_flags, TR_WARNING);
112                 break;
113             case EGO_KILL_DRAGON:
114                 if (one_in_(3))
115                     add_flag(o_ptr->art_flags, TR_RES_POIS);
116                 break;
117             case EGO_WEST:
118                 if (one_in_(3))
119                     add_flag(o_ptr->art_flags, TR_RES_FEAR);
120                 break;
121             case EGO_SLAYING_WEAPON:
122                 if (one_in_(3))
123                     o_ptr->dd *= 2;
124                 else {
125                     do {
126                         o_ptr->dd++;
127                     } while (one_in_(o_ptr->dd));
128
129                     do {
130                         o_ptr->ds++;
131                     } while (one_in_(o_ptr->ds));
132                 }
133
134                 if (one_in_(5)) {
135                     add_flag(o_ptr->art_flags, TR_BRAND_POIS);
136                 }
137                 if (o_ptr->tval == TV_SWORD && one_in_(3)) {
138                     add_flag(o_ptr->art_flags, TR_VORPAL);
139                 }
140                 break;
141             case EGO_TRUMP:
142                 if (one_in_(5))
143                     add_flag(o_ptr->art_flags, TR_SLAY_DEMON);
144                 if (one_in_(7))
145                     one_ability(o_ptr);
146                 break;
147             case EGO_PATTERN:
148                 if (one_in_(3))
149                     add_flag(o_ptr->art_flags, TR_HOLD_EXP);
150                 if (one_in_(3))
151                     add_flag(o_ptr->art_flags, TR_DEX);
152                 if (one_in_(5))
153                     add_flag(o_ptr->art_flags, TR_RES_FEAR);
154                 break;
155             case EGO_SHARPNESS:
156                 o_ptr->pval = (PARAMETER_VALUE)m_bonus(5, level) + 1;
157                 break;
158             case EGO_EARTHQUAKES:
159                 if (one_in_(3) && (level > 60))
160                     add_flag(o_ptr->art_flags, TR_BLOWS);
161                 else
162                     o_ptr->pval = (PARAMETER_VALUE)m_bonus(3, level);
163                 break;
164             case EGO_VAMPIRIC:
165                 if (one_in_(5))
166                     add_flag(o_ptr->art_flags, TR_SLAY_HUMAN);
167                 break;
168             case EGO_DEMON:
169
170                 if (one_in_(3))
171                     o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
172                 one_in_(3) ? add_flag(o_ptr->art_flags, TR_DRAIN_EXP)
173                            : one_in_(2) ? add_flag(o_ptr->art_flags, TR_DRAIN_HP) : add_flag(o_ptr->art_flags, TR_DRAIN_MANA);
174
175                 if (one_in_(3))
176                     add_flag(o_ptr->art_flags, TR_CHAOTIC);
177                 if (one_in_(4))
178                     add_flag(o_ptr->art_flags, TR_BLOWS);
179                 if (one_in_(5))
180                     add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
181                 if (one_in_(5))
182                     add_flag(o_ptr->art_flags, TR_CALL_DEMON);
183                 break;
184             }
185
186             if (!o_ptr->art_name) {
187                 while (one_in_(10L * o_ptr->dd * o_ptr->ds))
188                     o_ptr->dd++;
189
190                 if (o_ptr->dd > 9)
191                     o_ptr->dd = 9;
192             }
193         } else if (power < -1) {
194             if (randint0(MAX_DEPTH) < level) {
195                 while (TRUE) {
196                     o_ptr->name2 = get_random_ego(INVEN_RARM, FALSE);
197                     if (o_ptr->name2 == EGO_WEIRD && o_ptr->tval != TV_SWORD) {
198                         continue;
199                     }
200
201                     break;
202                 }
203
204                 switch (o_ptr->name2) {
205                 case EGO_MORGUL:
206                     if (one_in_(6))
207                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
208                     if (one_in_(3))
209                         o_ptr->curse_flags |= (TRC_HEAVY_CURSE);
210                     break;
211                 case EGO_WEIRD:
212                     if (one_in_(4))
213                         add_flag(o_ptr->art_flags, TR_BRAND_POIS);
214                     if (one_in_(4))
215                         add_flag(o_ptr->art_flags, TR_RES_NETHER);
216                     if (one_in_(3))
217                         add_flag(o_ptr->art_flags, TR_NO_MAGIC);
218                     if (one_in_(6))
219                         add_flag(o_ptr->art_flags, TR_NO_TELE);
220                     if (one_in_(6))
221                         add_flag(o_ptr->art_flags, TR_TY_CURSE);
222                     if (one_in_(6))
223                         add_flag(o_ptr->art_flags, TR_ADD_H_CURSE);
224                     break;
225                 }
226             }
227         }
228
229         break;
230     }
231     case TV_BOW: {
232         if (power > 1) {
233             /* power > 2 is debug only */
234             if (one_in_(20) || (power > 2)) {
235                 become_random_artifact(owner_ptr, o_ptr, FALSE);
236                 break;
237             }
238
239             o_ptr->name2 = get_random_ego(INVEN_BOW, TRUE);
240         }
241
242         break;
243     }
244     case TV_BOLT:
245     case TV_ARROW:
246     case TV_SHOT: {
247         if (power > 1) {
248             /* power > 2 is debug only */
249             if (power > 2) {
250                 become_random_artifact(owner_ptr, o_ptr, FALSE);
251                 break;
252             }
253
254             o_ptr->name2 = get_random_ego(INVEN_AMMO, TRUE);
255             switch (o_ptr->name2) {
256             case EGO_SLAYING_BOLT:
257                 o_ptr->dd++;
258                 break;
259             }
260
261             while (one_in_(10L * o_ptr->dd * o_ptr->ds))
262                 o_ptr->dd++;
263
264             if (o_ptr->dd > 9)
265                 o_ptr->dd = 9;
266         } else if (power < -1) {
267             if (randint0(MAX_DEPTH) < level) {
268                 o_ptr->name2 = get_random_ego(INVEN_AMMO, FALSE);
269             }
270         }
271
272         break;
273     }
274     }
275 }