OSDN Git Service

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