OSDN Git Service

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