OSDN Git Service

Merge pull request #2161 from Hourier/Add-This-Alignment
[hengbandforosx/hengbandosx.git] / src / object-enchant / others / apply-magic-others.cpp
1 /*!
2  * @brief 防具系のアイテムを強化して(恐らく床に)生成する処理
3  * @date 2020/06/02
4  * @author Hourier
5  * @todo ちょっと長い。要分割
6  */
7
8 #include "object-enchant/others/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 "system/monster-race-definition.h"
27 #include "system/object-type-definition.h"
28 #include "system/player-type-definition.h"
29 #include "util/bit-flags-calculator.h"
30 #include "view/display-messages.h"
31
32 /*!
33  * @brief その他雑多のオブジェクトに生成ランクごとの強化を与えるサブルーチン
34  * Apply magic to an item known to be "boring"
35  * @param player_ptr プレイヤーへの参照ポインタ
36  * @param o_ptr 強化を与えたいオブジェクトの構造体参照ポインタ
37  * @param power 生成ランク
38  * @details power > 2はデバッグ専用.
39  */
40 void apply_magic_others(PlayerType *player_ptr, ObjectType *o_ptr)
41 {
42     auto *k_ptr = &k_info[o_ptr->k_idx];
43
44     auto *floor_ptr = player_ptr->current_floor_ptr;
45     switch (o_ptr->tval) {
46     case ItemKindType::WHISTLE: {
47         break;
48     }
49     case ItemKindType::FLASK: {
50         o_ptr->xtra4 = o_ptr->pval;
51         o_ptr->pval = 0;
52         break;
53     }
54     case ItemKindType::WAND:
55     case ItemKindType::STAFF: {
56         /* The wand or staff gets a number of initial charges equal
57          * to between 1/2 (+1) and the full object kind's pval. -LM-
58          */
59         o_ptr->pval = k_ptr->pval / 2 + randint1((k_ptr->pval + 1) / 2);
60         break;
61     }
62     case ItemKindType::ROD: {
63         o_ptr->pval = k_ptr->pval;
64         break;
65     }
66     case ItemKindType::CAPTURE: {
67         o_ptr->pval = 0;
68         object_aware(player_ptr, o_ptr);
69         object_known(o_ptr);
70         break;
71     }
72     case ItemKindType::FIGURINE: {
73         PARAMETER_VALUE i = 1;
74         int check;
75         monster_race *r_ptr;
76         while (true) {
77             i = randint1(r_info.size() - 1);
78
79             if (!item_monster_okay(player_ptr, i))
80                 continue;
81             if (i == MON_TSUCHINOKO)
82                 continue;
83
84             r_ptr = &r_info[i];
85             check = (floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - floor_ptr->dun_level) : 0;
86             if (!r_ptr->rarity)
87                 continue;
88             if (r_ptr->rarity > 100)
89                 continue;
90             if (randint0(check))
91                 continue;
92
93             break;
94         }
95
96         o_ptr->pval = i;
97         if (one_in_(6))
98             o_ptr->curse_flags.set(CurseTraitType::CURSED);
99
100         break;
101     }
102     case ItemKindType::CORPSE: {
103         PARAMETER_VALUE i = 1;
104         int check;
105         uint32_t match = 0;
106         monster_race *r_ptr;
107         if (o_ptr->sval == SV_SKELETON) {
108             match = RF9_DROP_SKELETON;
109         } else if (o_ptr->sval == SV_CORPSE) {
110             match = RF9_DROP_CORPSE;
111         }
112
113         get_mon_num_prep(player_ptr, item_monster_okay, nullptr);
114         while (true) {
115             i = get_mon_num(player_ptr, 0, floor_ptr->dun_level, 0);
116             r_ptr = &r_info[i];
117             check = (floor_ptr->dun_level < r_ptr->level) ? (r_ptr->level - floor_ptr->dun_level) : 0;
118             if (!r_ptr->rarity)
119                 continue;
120             if (!(r_ptr->flags9 & match))
121                 continue;
122             if (randint0(check))
123                 continue;
124
125             break;
126         }
127
128         o_ptr->pval = i;
129         object_aware(player_ptr, o_ptr);
130         object_known(o_ptr);
131         break;
132     }
133     case ItemKindType::STATUE: {
134         PARAMETER_VALUE i = 1;
135         monster_race *r_ptr;
136         while (true) {
137             i = randint1(r_info.size() - 1);
138             r_ptr = &r_info[i];
139             if (!r_ptr->rarity)
140                 continue;
141
142             break;
143         }
144
145         o_ptr->pval = i;
146         if (cheat_peek) {
147             msg_format(_("%sの像", "Statue of %s"), r_ptr->name.c_str());
148         }
149
150         object_aware(player_ptr, o_ptr);
151         object_known(o_ptr);
152         break;
153     }
154     case ItemKindType::CHEST: {
155         DEPTH obj_level = k_info[o_ptr->k_idx].level;
156         if (obj_level <= 0)
157             break;
158
159         o_ptr->pval = randint1(obj_level);
160         if (o_ptr->sval == SV_CHEST_KANDUME)
161             o_ptr->pval = 6;
162
163         o_ptr->xtra3 = floor_ptr->dun_level + 5;
164         if (o_ptr->pval > 55)
165             o_ptr->pval = 55 + (byte)randint0(5);
166
167         break;
168     }
169
170     default:
171         break;
172     }
173 }