OSDN Git Service

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