OSDN Git Service

[Refactor] #37353 全復活系の効果をrestore_all_status()にまとめる。
[hengband/hengband.git] / src / cmd-zaprod.c
1 #include "angband.h"
2
3 /*!
4  * @brief \83\8d\83b\83h\82Ì\8cø\89Ê\82ð\94­\93®\82·\82é
5  * @param sval \83I\83u\83W\83F\83N\83g\82Ìsval
6  * @param dir \94­\93®\96Ú\95W\82Ì\95û\8cüID
7  * @param use_charge \83`\83\83\81[\83W\82ð\8fÁ\94ï\82µ\82½\82©\82Ç\82¤\82©\82ð\95Ô\82·\8eQ\8fÆ\83|\83C\83\93\83^
8  * @param powerful \8b­\97Í\94­\93®\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
9  * @param magic \96\82\93¹\8bï\8fp\8fã\82Ì\8f\88\97\9d\82È\82ç\82ÎTRUE
10  * @return \94­\93®\82É\82æ\82è\8cø\89Ê\93à\97e\82ª\8am\92è\82µ\82½\82È\82ç\82ÎTRUE\82ð\95Ô\82·
11  */
12 int rod_effect(OBJECT_SUBTYPE_VALUE sval, int dir, bool *use_charge, bool powerful, bool magic)
13 {
14         int ident = FALSE;
15         int lev = powerful ? p_ptr->lev * 2 : p_ptr->lev;
16         int detect_rad = powerful ? DETECT_RAD_DEFAULT * 3 / 2 : DETECT_RAD_DEFAULT;
17         int rad = powerful ? 3 : 2;
18
19         /* Unused */
20         (void)magic;
21
22         /* Analyze the rod */
23         switch (sval)
24         {
25         case SV_ROD_DETECT_TRAP:
26         {
27                 if (detect_traps(detect_rad, (bool)(dir ? FALSE : TRUE))) ident = TRUE;
28                 break;
29         }
30
31         case SV_ROD_DETECT_DOOR:
32         {
33                 if (detect_doors(detect_rad)) ident = TRUE;
34                 if (detect_stairs(detect_rad)) ident = TRUE;
35                 break;
36         }
37
38         case SV_ROD_IDENTIFY:
39         {
40                 if (powerful) {
41                         if (!identify_fully(FALSE)) *use_charge = FALSE;
42                 }
43                 else {
44                         if (!ident_spell(FALSE)) *use_charge = FALSE;
45                 }
46                 ident = TRUE;
47                 break;
48         }
49
50         case SV_ROD_RECALL:
51         {
52                 if (!word_of_recall()) *use_charge = FALSE;
53                 ident = TRUE;
54                 break;
55         }
56
57         case SV_ROD_ILLUMINATION:
58         {
59                 if (lite_area(damroll(2, 8), (powerful ? 4 : 2))) ident = TRUE;
60                 break;
61         }
62
63         case SV_ROD_MAPPING:
64         {
65                 map_area(powerful ? DETECT_RAD_MAP * 3 / 2 : DETECT_RAD_MAP);
66                 ident = TRUE;
67                 break;
68         }
69
70         case SV_ROD_DETECTION:
71         {
72                 detect_all(detect_rad);
73                 ident = TRUE;
74                 break;
75         }
76
77         case SV_ROD_PROBING:
78         {
79                 probing();
80                 ident = TRUE;
81                 break;
82         }
83
84         case SV_ROD_CURING:
85         {
86                 if (set_blind(0)) ident = TRUE;
87                 if (set_poisoned(0)) ident = TRUE;
88                 if (set_confused(0)) ident = TRUE;
89                 if (set_stun(0)) ident = TRUE;
90                 if (set_cut(0)) ident = TRUE;
91                 if (set_image(0)) ident = TRUE;
92                 if (set_shero(0, TRUE)) ident = TRUE;
93                 break;
94         }
95
96         case SV_ROD_HEALING:
97         {
98                 if(cure_critical_wounds(powerful ? 750 : 500)) ident = TRUE;
99                 break;
100         }
101
102         case SV_ROD_RESTORATION:
103         {
104                 if(restore_level()) ident = TRUE;
105                 if(restore_all_status()) ident = TRUE;
106                 break;
107         }
108
109         case SV_ROD_SPEED:
110         {
111                 if (set_fast(randint1(30) + (powerful ? 30 : 15), FALSE)) ident = TRUE;
112                 break;
113         }
114
115         case SV_ROD_PESTICIDE:
116         {
117                 if (dispel_monsters(powerful ? 8 : 4)) ident = TRUE;
118                 break;
119         }
120
121         case SV_ROD_TELEPORT_AWAY:
122         {
123                 int distance = MAX_SIGHT * (powerful ? 8 : 5);
124                 if (teleport_monster(dir, distance)) ident = TRUE;
125                 break;
126         }
127
128         case SV_ROD_DISARMING:
129         {
130                 if (disarm_trap(dir)) ident = TRUE;
131                 if (powerful && disarm_traps_touch()) ident = TRUE;
132                 break;
133         }
134
135         case SV_ROD_LITE:
136         {
137                 HIT_POINT dam = damroll((powerful ? 12 : 6), 8);
138                 msg_print(_("\90Â\82­\8bP\82­\8cõ\90ü\82ª\95ú\82½\82ê\82½\81B", "A line of blue shimmering light appears."));
139                 (void)lite_line(dir, dam);
140                 ident = TRUE;
141                 break;
142         }
143
144         case SV_ROD_SLEEP_MONSTER:
145         {
146                 if (sleep_monster(dir, lev)) ident = TRUE;
147                 break;
148         }
149
150         case SV_ROD_SLOW_MONSTER:
151         {
152                 if (slow_monster(dir, lev)) ident = TRUE;
153                 break;
154         }
155
156         case SV_ROD_HYPODYNAMIA:
157         {
158                 if (hypodynamic_bolt(dir, 70 + 3 * lev / 2)) ident = TRUE;
159                 break;
160         }
161
162         case SV_ROD_POLYMORPH:
163         {
164                 if (poly_monster(dir, lev)) ident = TRUE;
165                 break;
166         }
167
168         case SV_ROD_ACID_BOLT:
169         {
170                 fire_bolt_or_beam(10, GF_ACID, dir, damroll(6 + lev / 7, 8));
171                 ident = TRUE;
172                 break;
173         }
174
175         case SV_ROD_ELEC_BOLT:
176         {
177                 fire_bolt_or_beam(10, GF_ELEC, dir, damroll(4 + lev / 9, 8));
178                 ident = TRUE;
179                 break;
180         }
181
182         case SV_ROD_FIRE_BOLT:
183         {
184                 fire_bolt_or_beam(10, GF_FIRE, dir, damroll(7 + lev / 6, 8));
185                 ident = TRUE;
186                 break;
187         }
188
189         case SV_ROD_COLD_BOLT:
190         {
191                 fire_bolt_or_beam(10, GF_COLD, dir, damroll(5 + lev / 8, 8));
192                 ident = TRUE;
193                 break;
194         }
195
196         case SV_ROD_ACID_BALL:
197         {
198                 fire_ball(GF_ACID, dir, 60 + lev, rad);
199                 ident = TRUE;
200                 break;
201         }
202
203         case SV_ROD_ELEC_BALL:
204         {
205                 fire_ball(GF_ELEC, dir, 40 + lev, rad);
206                 ident = TRUE;
207                 break;
208         }
209
210         case SV_ROD_FIRE_BALL:
211         {
212                 fire_ball(GF_FIRE, dir, 70 + lev, rad);
213                 ident = TRUE;
214                 break;
215         }
216
217         case SV_ROD_COLD_BALL:
218         {
219                 fire_ball(GF_COLD, dir, 50 + lev, rad);
220                 ident = TRUE;
221                 break;
222         }
223
224         case SV_ROD_HAVOC:
225         {
226                 call_chaos();
227                 ident = TRUE;
228                 break;
229         }
230
231         case SV_ROD_STONE_TO_MUD:
232         {
233                 HIT_POINT dam = powerful ? 40 + randint1(60) : 20 + randint1(30);
234                 if (wall_to_mud(dir, dam)) ident = TRUE;
235                 break;
236         }
237
238         case SV_ROD_AGGRAVATE:
239         {
240                 aggravate_monsters(0);
241                 ident = TRUE;
242                 break;
243         }
244         }
245         return ident;
246 }
247
248 /*!
249 * @brief \83\8d\83b\83h\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83T\83u\83\8b\81[\83`\83\93 /
250 * Activate (zap) a Rod
251 * @param item \8eg\82¤\83I\83u\83W\83F\83N\83g\82Ì\8f\8a\8e\9d\95iID
252 * @return \82È\82µ
253 * @details
254 * <pre>
255 * Unstack fully charged rods as needed.
256 * Hack -- rods of perception/genocide can be "cancelled"
257 * All rods can be cancelled at the "Direction?" prompt
258 * pvals are defined for each rod in k_info. -LM-
259 * </pre>
260 */
261 void do_cmd_zap_rod_aux(int item)
262 {
263         int ident, chance, lev, fail;
264         int dir = 0;
265         object_type *o_ptr;
266         bool success;
267
268         /* Hack -- let perception get aborted */
269         bool use_charge = TRUE;
270
271         object_kind *k_ptr;
272
273         /* Get the item (in the pack) */
274         if (item >= 0)
275         {
276                 o_ptr = &inventory[item];
277         }
278
279         /* Get the item (on the floor) */
280         else
281         {
282                 o_ptr = &o_list[0 - item];
283         }
284
285
286         /* Mega-Hack -- refuse to zap a pile from the ground */
287         if ((item < 0) && (o_ptr->number > 1))
288         {
289                 msg_print(_("\82Ü\82¸\82Í\83\8d\83b\83h\82ð\8fE\82í\82È\82¯\82ê\82Î\81B", "You must first pick up the rods."));
290                 return;
291         }
292
293
294         /* Get a direction (unless KNOWN not to need it) */
295         if (((o_ptr->sval >= SV_ROD_MIN_DIRECTION) && (o_ptr->sval != SV_ROD_HAVOC) && (o_ptr->sval != SV_ROD_AGGRAVATE) && (o_ptr->sval != SV_ROD_PESTICIDE)) ||
296                 !object_is_aware(o_ptr))
297         {
298                 /* Get a direction, allow cancel */
299                 if (!get_aim_dir(&dir)) return;
300         }
301
302
303         /* Take a turn */
304         p_ptr->energy_use = 100;
305
306         /* Extract the item level */
307         lev = k_info[o_ptr->k_idx].level;
308
309         /* Base chance of success */
310         chance = p_ptr->skill_dev;
311
312         /* Confusion hurts skill */
313         if (p_ptr->confused) chance = chance / 2;
314
315         fail = lev + 5;
316         if (chance > fail) fail -= (chance - fail) * 2;
317         else chance -= (fail - chance) * 2;
318         if (fail < USE_DEVICE) fail = USE_DEVICE;
319         if (chance < USE_DEVICE) chance = USE_DEVICE;
320
321         if (world_player)
322         {
323                 if (flush_failure) flush();
324                 msg_print(_("\8e~\82Ü\82Á\82½\8e\9e\82Ì\92\86\82Å\82Í\82¤\82Ü\82­\93­\82©\82È\82¢\82æ\82¤\82¾\81B", "Nothing happen. Maybe this rod is freezing too."));
325                 sound(SOUND_FAIL);
326                 return;
327         }
328
329         if (p_ptr->pclass == CLASS_BERSERKER) success = FALSE;
330         else if (chance > fail)
331         {
332                 if (randint0(chance * 2) < fail) success = FALSE;
333                 else success = TRUE;
334         }
335         else
336         {
337                 if (randint0(fail * 2) < chance) success = TRUE;
338                 else success = FALSE;
339         }
340
341         /* Roll for usage */
342         if (!success)
343         {
344                 if (flush_failure) flush();
345                 msg_print(_("\82¤\82Ü\82­\83\8d\83b\83h\82ð\8eg\82¦\82È\82©\82Á\82½\81B", "You failed to use the rod properly."));
346                 sound(SOUND_FAIL);
347                 return;
348         }
349
350         k_ptr = &k_info[o_ptr->k_idx];
351
352         /* A single rod is still charging */
353         if ((o_ptr->number == 1) && (o_ptr->timeout))
354         {
355                 if (flush_failure) flush();
356                 msg_print(_("\82±\82Ì\83\8d\83b\83h\82Í\82Ü\82¾\96\82\97Í\82ð\8f[\93U\82µ\82Ä\82¢\82é\8dÅ\92\86\82¾\81B", "The rod is still charging."));
357                 return;
358         }
359         /* A stack of rods lacks enough energy. */
360         else if ((o_ptr->number > 1) && (o_ptr->timeout > k_ptr->pval * (o_ptr->number - 1)))
361         {
362                 if (flush_failure) flush();
363                 msg_print(_("\82»\82Ì\83\8d\83b\83h\82Í\82Ü\82¾\8f[\93U\92\86\82Å\82·\81B", "The rods are all still charging."));
364                 return;
365         }
366
367         /* Sound */
368         sound(SOUND_ZAP);
369
370         ident = rod_effect(o_ptr->sval, dir, &use_charge, FALSE, FALSE);
371
372         /* Increase the timeout by the rod kind's pval. -LM- */
373         if (use_charge) o_ptr->timeout += k_ptr->pval;
374
375         /* Combine / Reorder the pack (later) */
376         p_ptr->notice |= (PN_COMBINE | PN_REORDER);
377
378         if (!(object_is_aware(o_ptr)))
379         {
380                 chg_virtue(V_PATIENCE, -1);
381                 chg_virtue(V_CHANCE, 1);
382                 chg_virtue(V_KNOWLEDGE, -1);
383         }
384
385         /* Tried the object */
386         object_tried(o_ptr);
387
388         /* Successfully determined the object function */
389         if (ident && !object_is_aware(o_ptr))
390         {
391                 object_aware(o_ptr);
392                 gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
393         }
394
395         /* Window stuff */
396         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
397 }
398
399 /*!
400 * @brief \83\8d\83b\83h\82ð\8eg\82¤\83R\83}\83\93\83h\82Ì\83\81\83C\83\93\83\8b\81[\83`\83\93 /
401 * @return \82È\82µ
402 */
403 void do_cmd_zap_rod(void)
404 {
405         OBJECT_IDX item;
406         cptr q, s;
407
408         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
409         {
410                 set_action(ACTION_NONE);
411         }
412
413         /* Restrict choices to rods */
414         item_tester_tval = TV_ROD;
415
416         /* Get an item */
417         q = _("\82Ç\82Ì\83\8d\83b\83h\82ð\90U\82è\82Ü\82·\82©? ", "Zap which rod? ");
418         s = _("\8eg\82¦\82é\83\8d\83b\83h\82ª\82È\82¢\81B", "You have no rod to zap.");
419
420         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
421
422         /* Zap the rod */
423         do_cmd_zap_rod_aux(item);
424 }