OSDN Git Service

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