OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Relocate-score-server' into...
[hengband/hengband.git] / src / object-enchant / apply-magic-others.c
1 /*!
2  * todo ちょっと長い。要分割
3  * @brief 防具系のアイテムを強化して(恐らく床に)生成する処理
4  * @date 2020/06/02
5  * @author Hourier
6  */
7
8 #include "object-enchant/apply-magic-others.h"
9 #include "artifact/random-art-generator.h"
10 #include "game-option/cheat-options.h"
11 #include "inventory/inventory-slot-types.h"
12 #include "monster-race/monster-race-hook.h"
13 #include "monster-race/monster-race.h"
14 #include "monster-race/race-flags9.h"
15 #include "monster-race/race-indice-types.h"
16 #include "monster/monster-list.h"
17 #include "monster/monster-util.h"
18 #include "object-enchant/object-ego.h"
19 #include "object-enchant/tr-types.h"
20 #include "object-enchant/trc-types.h"
21 #include "object/object-kind.h"
22 #include "perception/object-perception.h"
23 #include "sv-definition/sv-lite-types.h"
24 #include "sv-definition/sv-other-types.h"
25 #include "system/floor-type-definition.h"
26 #include "util/bit-flags-calculator.h"
27 #include "view/display-messages.h"
28
29 /*!
30  * @brief その他雑多のオブジェクトに生成ランクごとの強化を与えるサブルーチン
31  * Apply magic to an item known to be "boring"
32  * @param owner_ptr プレーヤーへの参照ポインタ
33  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
34  * @param power 生成ランク
35  * @return なし
36  * @details
37  * Hack -- note the special code for various items
38  */
39 void apply_magic_others(player_type *owner_ptr, object_type *o_ptr, int power)
40 {
41     object_kind *k_ptr = &k_info[o_ptr->k_idx];
42
43     floor_type *floor_ptr = owner_ptr->current_floor_ptr;
44     switch (o_ptr->tval) {
45     case TV_WHISTLE: {
46         break;
47     }
48     case TV_FLASK: {
49         o_ptr->xtra4 = o_ptr->pval;
50         o_ptr->pval = 0;
51         break;
52     }
53     case TV_LITE: {
54         if (o_ptr->sval == SV_LITE_TORCH) {
55             if (o_ptr->pval > 0)
56                 o_ptr->xtra4 = randint1(o_ptr->pval);
57             o_ptr->pval = 0;
58         }
59
60         if (o_ptr->sval == SV_LITE_LANTERN) {
61             if (o_ptr->pval > 0)
62                 o_ptr->xtra4 = randint1(o_ptr->pval);
63             o_ptr->pval = 0;
64         }
65
66         /* power > 2 is debug only */
67         if (power > 2) {
68             become_random_artifact(owner_ptr, o_ptr, FALSE);
69         } else if ((power == 2) || ((power == 1) && one_in_(3))) {
70             while (!o_ptr->name2) {
71                 while (TRUE) {
72                     bool okay_flag = TRUE;
73
74                     o_ptr->name2 = get_random_ego(INVEN_LITE, TRUE);
75
76                     switch (o_ptr->name2) {
77                     case EGO_LITE_LONG:
78                         if (o_ptr->sval == SV_LITE_FEANOR)
79                             okay_flag = FALSE;
80                     }
81
82                     if (okay_flag)
83                         break;
84                 }
85             }
86         } else if (power == -2) {
87             o_ptr->name2 = get_random_ego(INVEN_LITE, FALSE);
88             switch (o_ptr->name2) {
89             case EGO_LITE_DARKNESS:
90                 o_ptr->xtra4 = 0;
91
92                 if (o_ptr->sval == SV_LITE_TORCH) {
93                     add_flag(o_ptr->art_flags, TR_LITE_M1);
94                 } else if (o_ptr->sval == SV_LITE_LANTERN) {
95                     add_flag(o_ptr->art_flags, TR_LITE_M2);
96                 } else if (o_ptr->sval == SV_LITE_FEANOR) {
97                     add_flag(o_ptr->art_flags, TR_LITE_M3);
98                 }
99                 break;
100             }
101         }
102
103         break;
104     }
105     case TV_WAND:
106     case TV_STAFF: {
107         /* The wand or staff gets a number of initial charges equal
108          * to between 1/2 (+1) and the full object kind's pval. -LM-
109          */
110         o_ptr->pval = k_ptr->pval / 2 + randint1((k_ptr->pval + 1) / 2);
111         break;
112     }
113     case TV_ROD: {
114         o_ptr->pval = k_ptr->pval;
115         break;
116     }
117     case TV_CAPTURE: {
118         o_ptr->pval = 0;
119         object_aware(owner_ptr, o_ptr);
120         object_known(o_ptr);
121         break;
122     }
123     case TV_FIGURINE: {
124         PARAMETER_VALUE i = 1;
125         int check;
126         monster_race *r_ptr;
127         while (TRUE) {
128             i = randint1(max_r_idx - 1);
129
130             if (!item_monster_okay(owner_ptr, i))
131                 continue;
132             if (i == MON_TSUCHINOKO)
133                 continue;
134
135             r_ptr = &r_info[i];
136             check = (floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - floor_ptr->dun_level) : 0;
137             if (!r_ptr->rarity)
138                 continue;
139             if (r_ptr->rarity > 100)
140                 continue;
141             if (randint0(check))
142                 continue;
143
144             break;
145         }
146
147         o_ptr->pval = i;
148         if (one_in_(6))
149             o_ptr->curse_flags |= TRC_CURSED;
150
151         break;
152     }
153     case TV_CORPSE: {
154         PARAMETER_VALUE i = 1;
155         int check;
156         u32b match = 0;
157         monster_race *r_ptr;
158         if (o_ptr->sval == SV_SKELETON) {
159             match = RF9_DROP_SKELETON;
160         } else if (o_ptr->sval == SV_CORPSE) {
161             match = RF9_DROP_CORPSE;
162         }
163
164         get_mon_num_prep(owner_ptr, item_monster_okay, NULL);
165         while (TRUE) {
166             i = get_mon_num(owner_ptr, 0, floor_ptr->dun_level, 0);
167             r_ptr = &r_info[i];
168             check = (floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - floor_ptr->dun_level) : 0;
169             if (!r_ptr->rarity)
170                 continue;
171             if (!(r_ptr->flags9 & match))
172                 continue;
173             if (randint0(check))
174                 continue;
175
176             break;
177         }
178
179         o_ptr->pval = i;
180         object_aware(owner_ptr, o_ptr);
181         object_known(o_ptr);
182         break;
183     }
184     case TV_STATUE: {
185         PARAMETER_VALUE i = 1;
186         monster_race *r_ptr;
187         while (TRUE) {
188             i = randint1(max_r_idx - 1);
189             r_ptr = &r_info[i];
190             if (!r_ptr->rarity)
191                 continue;
192
193             break;
194         }
195
196         o_ptr->pval = i;
197         if (cheat_peek) {
198             msg_format(_("%sの像", "Statue of %s"), r_name + r_ptr->name);
199         }
200
201         object_aware(owner_ptr, o_ptr);
202         object_known(o_ptr);
203         break;
204     }
205     case TV_CHEST: {
206         DEPTH obj_level = k_info[o_ptr->k_idx].level;
207         if (obj_level <= 0)
208             break;
209
210         o_ptr->pval = randint1(obj_level);
211         if (o_ptr->sval == SV_CHEST_KANDUME)
212             o_ptr->pval = 6;
213
214         o_ptr->xtra3 = floor_ptr->dun_level + 5;
215         if (o_ptr->pval > 55)
216             o_ptr->pval = 55 + (byte)randint0(5);
217
218         break;
219     }
220     }
221 }