OSDN Git Service

[Refactor] enum spells-typeをenum class AttributeTypeに置換
[hengbandforosx/hengbandosx.git] / src / cmd-item / cmd-zaprod.cpp
1 #include "cmd-item/cmd-zaprod.h"
2 #include "action/action-limited.h"
3 #include "floor/floor-object.h"
4 #include "object-enchant/special-object-flags.h"
5 #include "object-use/zaprod-execution.h"
6 #include "object/item-tester-hooker.h"
7 #include "object/item-use-flags.h"
8 #include "player-base/player-class.h"
9 #include "player-info/class-info.h"
10 #include "player-info/samurai-data-type.h"
11 #include "player/attack-defense-types.h"
12 #include "player/special-defense-types.h"
13 #include "spell-kind/spells-beam.h"
14 #include "spell-kind/spells-detection.h"
15 #include "spell-kind/spells-floor.h"
16 #include "spell-kind/spells-launcher.h"
17 #include "spell-kind/spells-lite.h"
18 #include "spell-kind/spells-neighbor.h"
19 #include "spell-kind/spells-perception.h"
20 #include "spell-kind/spells-random.h"
21 #include "spell-kind/spells-sight.h"
22 #include "spell-kind/spells-specific-bolt.h"
23 #include "spell-kind/spells-teleport.h"
24 #include "spell-kind/spells-world.h"
25 #include "effect/attribute-types.h"
26 #include "spell/spells-status.h"
27 #include "status/action-setter.h"
28 #include "status/buff-setter.h"
29 #include "status/experience.h"
30 #include "status/shape-changer.h"
31 #include "sv-definition/sv-rod-types.h"
32 #include "system/object-type-definition.h"
33 #include "system/player-type-definition.h"
34 #include "view/display-messages.h"
35
36 /*!
37  * @brief ロッドの効果を発動する
38  * @param player_ptr プレイヤーへの参照ポインタ
39  * @param sval オブジェクトのsval
40  * @param dir 発動目標の方向ID
41  * @param use_charge チャージを消費したかどうかを返す参照ポインタ
42  * @param powerful 強力発動上の処理ならばTRUE
43  * @return 発動により効果内容が確定したならばTRUEを返す
44  */
45 int rod_effect(player_type *player_ptr, OBJECT_SUBTYPE_VALUE sval, DIRECTION dir, bool *use_charge, bool powerful)
46 {
47     int ident = false;
48     PLAYER_LEVEL lev = powerful ? player_ptr->lev * 2 : player_ptr->lev;
49     POSITION detect_rad = powerful ? DETECT_RAD_DEFAULT * 3 / 2 : DETECT_RAD_DEFAULT;
50     POSITION rad = powerful ? 3 : 2;
51
52     /* Analyze the rod */
53     switch (sval) {
54     case SV_ROD_DETECT_TRAP: {
55         if (detect_traps(player_ptr, detect_rad, dir == 0))
56             ident = true;
57         break;
58     }
59
60     case SV_ROD_DETECT_DOOR: {
61         if (detect_doors(player_ptr, detect_rad))
62             ident = true;
63         if (detect_stairs(player_ptr, detect_rad))
64             ident = true;
65         break;
66     }
67
68     case SV_ROD_IDENTIFY: {
69         if (powerful) {
70             if (!identify_fully(player_ptr, false))
71                 *use_charge = false;
72         } else {
73             if (!ident_spell(player_ptr, false))
74                 *use_charge = false;
75         }
76         ident = true;
77         break;
78     }
79
80     case SV_ROD_RECALL: {
81         if (!recall_player(player_ptr, randint0(21) + 15))
82             *use_charge = false;
83         ident = true;
84         break;
85     }
86
87     case SV_ROD_ILLUMINATION: {
88         if (lite_area(player_ptr, damroll(2, 8), (powerful ? 4 : 2)))
89             ident = true;
90         break;
91     }
92
93     case SV_ROD_MAPPING: {
94         map_area(player_ptr, powerful ? DETECT_RAD_MAP * 3 / 2 : DETECT_RAD_MAP);
95         ident = true;
96         break;
97     }
98
99     case SV_ROD_DETECTION: {
100         detect_all(player_ptr, detect_rad);
101         ident = true;
102         break;
103     }
104
105     case SV_ROD_PROBING: {
106         probing(player_ptr);
107         ident = true;
108         break;
109     }
110
111     case SV_ROD_CURING: {
112         if (true_healing(player_ptr, 0))
113             ident = true;
114         if (set_shero(player_ptr, 0, true))
115             ident = true;
116         break;
117     }
118
119     case SV_ROD_HEALING: {
120         if (cure_critical_wounds(player_ptr, powerful ? 750 : 500))
121             ident = true;
122         break;
123     }
124
125     case SV_ROD_RESTORATION: {
126         if (restore_level(player_ptr))
127             ident = true;
128         if (restore_all_status(player_ptr))
129             ident = true;
130         break;
131     }
132
133     case SV_ROD_SPEED: {
134         if (set_fast(player_ptr, randint1(30) + (powerful ? 30 : 15), false))
135             ident = true;
136         break;
137     }
138
139     case SV_ROD_PESTICIDE: {
140         if (dispel_monsters(player_ptr, powerful ? 8 : 4))
141             ident = true;
142         break;
143     }
144
145     case SV_ROD_TELEPORT_AWAY: {
146         int distance = MAX_SIGHT * (powerful ? 8 : 5);
147         if (teleport_monster(player_ptr, dir, distance))
148             ident = true;
149         break;
150     }
151
152     case SV_ROD_DISARMING: {
153         if (disarm_trap(player_ptr, dir))
154             ident = true;
155         if (powerful && disarm_traps_touch(player_ptr))
156             ident = true;
157         break;
158     }
159
160     case SV_ROD_LITE: {
161         HIT_POINT dam = damroll((powerful ? 12 : 6), 8);
162         msg_print(_("青く輝く光線が放たれた。", "A line of blue shimmering light appears."));
163         (void)lite_line(player_ptr, dir, dam);
164         ident = true;
165         break;
166     }
167
168     case SV_ROD_SLEEP_MONSTER: {
169         if (sleep_monster(player_ptr, dir, lev))
170             ident = true;
171         break;
172     }
173
174     case SV_ROD_SLOW_MONSTER: {
175         if (slow_monster(player_ptr, dir, lev))
176             ident = true;
177         break;
178     }
179
180     case SV_ROD_HYPODYNAMIA: {
181         if (hypodynamic_bolt(player_ptr, dir, 70 + 3 * lev / 2))
182             ident = true;
183         break;
184     }
185
186     case SV_ROD_POLYMORPH: {
187         if (poly_monster(player_ptr, dir, lev))
188             ident = true;
189         break;
190     }
191
192     case SV_ROD_ACID_BOLT: {
193         fire_bolt_or_beam(player_ptr, 10, AttributeType::ACID, dir, damroll(6 + lev / 7, 8));
194         ident = true;
195         break;
196     }
197
198     case SV_ROD_ELEC_BOLT: {
199         fire_bolt_or_beam(player_ptr, 10, AttributeType::ELEC, dir, damroll(4 + lev / 9, 8));
200         ident = true;
201         break;
202     }
203
204     case SV_ROD_FIRE_BOLT: {
205         fire_bolt_or_beam(player_ptr, 10, AttributeType::FIRE, dir, damroll(7 + lev / 6, 8));
206         ident = true;
207         break;
208     }
209
210     case SV_ROD_COLD_BOLT: {
211         fire_bolt_or_beam(player_ptr, 10, AttributeType::COLD, dir, damroll(5 + lev / 8, 8));
212         ident = true;
213         break;
214     }
215
216     case SV_ROD_ACID_BALL: {
217         fire_ball(player_ptr, AttributeType::ACID, dir, 60 + lev, rad);
218         ident = true;
219         break;
220     }
221
222     case SV_ROD_ELEC_BALL: {
223         fire_ball(player_ptr, AttributeType::ELEC, dir, 40 + lev, rad);
224         ident = true;
225         break;
226     }
227
228     case SV_ROD_FIRE_BALL: {
229         fire_ball(player_ptr, AttributeType::FIRE, dir, 70 + lev, rad);
230         ident = true;
231         break;
232     }
233
234     case SV_ROD_COLD_BALL: {
235         fire_ball(player_ptr, AttributeType::COLD, dir, 50 + lev, rad);
236         ident = true;
237         break;
238     }
239
240     case SV_ROD_HAVOC: {
241         call_chaos(player_ptr);
242         ident = true;
243         break;
244     }
245
246     case SV_ROD_STONE_TO_MUD: {
247         HIT_POINT dam = powerful ? 40 + randint1(60) : 20 + randint1(30);
248         if (wall_to_mud(player_ptr, dir, dam))
249             ident = true;
250         break;
251     }
252
253     case SV_ROD_AGGRAVATE: {
254         aggravate_monsters(player_ptr, 0);
255         ident = true;
256         break;
257     }
258     }
259     return ident;
260 }
261
262 /*!
263  * @brief ロッドを使うコマンドのメインルーチン /
264  * @param player_ptr プレイヤーへの参照ポインタ
265  */
266 void do_cmd_zap_rod(player_type *player_ptr)
267 {
268     if (player_ptr->wild_mode) {
269         return;
270     }
271
272     if (cmd_limit_arena(player_ptr)) {
273         return;
274     }
275
276     PlayerClass(player_ptr).break_samurai_stance({ SamuraiStance::MUSOU, SamuraiStance::KOUKIJIN });
277
278     auto q = _("どのロッドを振りますか? ", "Zap which rod? ");
279     auto s = _("使えるロッドがない。", "You have no rod to zap.");
280     OBJECT_IDX item;
281     if (!choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), TvalItemTester(ItemKindType::ROD))) {
282         return;
283     }
284
285         ObjectZapRodEntity(player_ptr).execute(item);
286 }