OSDN Git Service

[Refactor] #37353 プレイヤーのロッド使用処理を cmd-zaprod.c/h に分離。 / Separate player's 'zap rod...
[hengband/hengband.git] / src / cmd6.c
1 /*!
2  * @file cmd6.c
3  * @brief プレイヤーのアイテムに関するコマンドの実装2 / Spell/Prayer commands
4  * @date 2014/01/27
5  * @author
6  * <pre>
7  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  * 2014 Deskull rearranged comment for Doxygen.\n
12  * </pre>
13  * @details
14  * <pre>
15  * This file includes code for eating food, drinking potions,
16  * reading scrolls, aiming wands, using staffs, zapping rods,
17  * and activating artifacts.
18  *
19  * In all cases, if the player becomes "aware" of the item's use
20  * by testing it, mark it as "aware" and reward some experience
21  * based on the object's level, always rounding up.  If the player
22  * remains "unaware", mark that object "kind" as "tried".
23  *
24  * This code now correctly handles the unstacking of wands, staffs,
25  * and rods.  Note the overly paranoid warning about potential pack
26  * overflow, which allows the player to use and drop a stacked item.
27  *
28  * In all "unstacking" scenarios, the "used" object is "carried" as if
29  * the player had just picked it up.  In particular, this means that if
30  * the use of an item induces pack overflow, that item will be dropped.
31  *
32  * For simplicity, these routines induce a full "pack reorganization"
33  * which not only combines similar items, but also reorganizes various
34  * items to obey the current "sorting" method.  This may require about
35  * 400 item comparisons, but only occasionally.
36  *
37  * There may be a BIG problem with any "effect" that can cause "changes"
38  * to the inventory.  For example, a "scroll of recharging" can cause
39  * a wand/staff to "disappear", moving the inventory up.  Luckily, the
40  * scrolls all appear BEFORE the staffs/wands, so this is not a problem.
41  * But, for example, a "staff of recharging" could cause MAJOR problems.
42  * In such a case, it will be best to either (1) "postpone" the effect
43  * until the end of the function, or (2) "change" the effect, say, into
44  * giving a staff "negative" charges, or "turning a staff into a stick".
45  * It seems as though a "rod of recharging" might in fact cause problems.
46  * The basic problem is that the act of recharging (and destroying) an
47  * item causes the inducer of that action to "move", causing "o_ptr" to
48  * no longer point at the correct item, with horrifying results.
49  *
50  * Note that food/potions/scrolls no longer use bit-flags for effects,
51  * but instead use the "sval" (which is also used to sort the objects).
52  * </pre>
53  */
54
55 #include "angband.h"
56 #include "selfinfo.h"
57 #include "cmd-activate.h"
58 #include "cmd-eat.h"
59 #include "cmd-quaff.h"
60 #include "cmd-read.h"
61 #include "cmd-usestaff.h"
62 #include "cmd-zaprod.h"
63 #include "cmd-zapwand.h"
64
65
66 /*!
67  * @brief 『一つの指輪』の効果処理 /
68  * Hack -- activate the ring of power
69  * @param dir 発動の方向ID
70  * @return なし
71  */
72 void ring_of_power(int dir)
73 {
74         /* Pick a random effect */
75         switch (randint1(10))
76         {
77                 case 1:
78                 case 2:
79                 {
80                         /* Message */
81                         msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
82                         sound(SOUND_EVIL);
83
84                         /* Decrease all stats (permanently) */
85                         (void)dec_stat(A_STR, 50, TRUE);
86                         (void)dec_stat(A_INT, 50, TRUE);
87                         (void)dec_stat(A_WIS, 50, TRUE);
88                         (void)dec_stat(A_DEX, 50, TRUE);
89                         (void)dec_stat(A_CON, 50, TRUE);
90                         (void)dec_stat(A_CHR, 50, TRUE);
91
92                         /* Lose some experience (permanently) */
93                         p_ptr->exp -= (p_ptr->exp / 4);
94                         p_ptr->max_exp -= (p_ptr->exp / 4);
95                         check_experience();
96
97                         break;
98                 }
99
100                 case 3:
101                 {
102                         /* Message */
103                         msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
104
105                         /* Dispel monsters */
106                         dispel_monsters(1000);
107
108                         break;
109                 }
110
111                 case 4:
112                 case 5:
113                 case 6:
114                 {
115                         /* Mana Ball */
116                         fire_ball(GF_MANA, dir, 600, 3);
117
118                         break;
119                 }
120
121                 case 7:
122                 case 8:
123                 case 9:
124                 case 10:
125                 {
126                         /* Mana Bolt */
127                         fire_bolt(GF_MANA, dir, 500);
128
129                         break;
130                 }
131         }
132 }
133
134 /*!
135  * @brief オブジェクトをプレイヤーが簡易使用コマンドで利用できるかを判定する /
136  * Hook to determine if an object is useable
137  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
138  * @return 利用可能ならばTRUEを返す
139  */
140 static bool item_tester_hook_use(object_type *o_ptr)
141 {
142         u32b flgs[TR_FLAG_SIZE];
143
144         /* Ammo */
145         if (o_ptr->tval == p_ptr->tval_ammo)
146                 return (TRUE);
147
148         /* Useable object */
149         switch (o_ptr->tval)
150         {
151                 case TV_SPIKE:
152                 case TV_STAFF:
153                 case TV_WAND:
154                 case TV_ROD:
155                 case TV_SCROLL:
156                 case TV_POTION:
157                 case TV_FOOD:
158                 {
159                         return (TRUE);
160                 }
161
162                 default:
163                 {
164                         int i;
165
166                         /* Not known */
167                         if (!object_is_known(o_ptr)) return (FALSE);
168
169                         /* HACK - only items from the equipment can be activated */
170                         for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
171                         {
172                                 if (&inventory[i] == o_ptr)
173                                 {
174                                         /* Extract the flags */
175                                         object_flags(o_ptr, flgs);
176
177                                         /* Check activation flag */
178                                         if (have_flag(flgs, TR_ACTIVATE)) return (TRUE);
179                                 }
180                         }
181                 }
182         }
183
184         /* Assume not */
185         return (FALSE);
186 }
187
188
189 /*!
190  * @brief アイテムを汎用的に「使う」コマンドのメインルーチン /
191  * Use an item
192  * @return なし
193  * @details
194  * XXX - Add actions for other item types
195  */
196 void do_cmd_use(void)
197 {
198         OBJECT_IDX item;
199         object_type *o_ptr;
200         cptr        q, s;
201
202         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
203         {
204                 set_action(ACTION_NONE);
205         }
206
207         item_tester_no_ryoute = TRUE;
208         /* Prepare the hook */
209         item_tester_hook = item_tester_hook_use;
210
211         /* Get an item */
212         q = _("どれを使いますか?", "Use which item? ");
213         s = _("使えるものがありません。", "You have nothing to use.");
214
215         if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
216
217         /* Get the item (in the pack) */
218         if (item >= 0)
219         {
220                 o_ptr = &inventory[item];
221         }
222         /* Get the item (on the floor) */
223         else
224         {
225                 o_ptr = &o_list[0 - item];
226         }
227
228         switch (o_ptr->tval)
229         {
230                 /* Spike a door */
231                 case TV_SPIKE:
232                 {
233                         do_cmd_spike();
234                         break;
235                 }
236
237                 /* Eat some food */
238                 case TV_FOOD:
239                 {
240                         do_cmd_eat_food_aux(item);
241                         break;
242                 }
243
244                 /* Aim a wand */
245                 case TV_WAND:
246                 {
247                         do_cmd_aim_wand_aux(item);
248                         break;
249                 }
250
251                 /* Use a staff */
252                 case TV_STAFF:
253                 {
254                         do_cmd_use_staff_aux(item);
255                         break;
256                 }
257
258                 /* Zap a rod */
259                 case TV_ROD:
260                 {
261                         do_cmd_zap_rod_aux(item);
262                         break;
263                 }
264
265                 /* Quaff a potion */
266                 case TV_POTION:
267                 {
268                         do_cmd_quaff_potion_aux(item);
269                         break;
270                 }
271
272                 /* Read a scroll */
273                 case TV_SCROLL:
274                 {
275                         /* Check some conditions */
276                         if (p_ptr->blind)
277                         {
278                                 msg_print(_("目が見えない。", "You can't see anything."));
279                                 return;
280                         }
281                         if (no_lite())
282                         {
283                                 msg_print(_("明かりがないので、暗くて読めない。", "You have no light to read by."));
284                                 return;
285                         }
286                         if (p_ptr->confused)
287                         {
288                                 msg_print(_("混乱していて読めない!", "You are too confused!"));
289                                 return;
290                         }
291
292                   do_cmd_read_scroll_aux(item, TRUE);
293                   break;
294                 }
295
296                 /* Fire ammo */
297                 case TV_SHOT:
298                 case TV_ARROW:
299                 case TV_BOLT:
300                 {
301                         do_cmd_fire_aux(item, &inventory[INVEN_BOW]);
302                         break;
303                 }
304
305                 /* Activate an artifact */
306                 default:
307                 {
308                         do_cmd_activate_aux(item);
309                         break;
310                 }
311         }
312 }
313
314 /*!
315  * @brief 魔道具術師の取り込んだ魔力一覧から選択/閲覧する /
316  * @param only_browse 閲覧するだけならばTRUE
317  * @return 選択した魔力のID、キャンセルならば-1を返す
318  */
319 static OBJECT_SUBTYPE_VALUE select_magic_eater(bool only_browse)
320 {
321         OBJECT_SUBTYPE_VALUE ext = 0;
322         char choice;
323         bool flag, request_list;
324         OBJECT_TYPE_VALUE tval = 0;
325         int             ask = TRUE;
326         OBJECT_SUBTYPE_VALUE i = 0;
327         char            out_val[160];
328
329         int menu_line = (use_menu ? 1 : 0);
330
331 #ifdef ALLOW_REPEAT
332         COMMAND_CODE sn;
333         if (repeat_pull(&sn))
334         {
335                 /* Verify the spell */
336                 if (sn >= EATER_EXT*2 && !(p_ptr->magic_num1[sn] > k_info[lookup_kind(TV_ROD, sn-EATER_EXT*2)].pval * (p_ptr->magic_num2[sn] - 1) * EATER_ROD_CHARGE))
337                         return sn;
338                 else if (sn < EATER_EXT*2 && !(p_ptr->magic_num1[sn] < EATER_CHARGE))
339                         return sn;
340         }
341         
342 #endif /* ALLOW_REPEAT */
343
344         for (i = 0; i < 108; i++)
345         {
346                 if (p_ptr->magic_num2[i]) break;
347         }
348         if (i == 108)
349         {
350                 msg_print(_("魔法を覚えていない!", "You don't have any magic!"));
351                 return -1;
352         }
353
354         if (use_menu)
355         {
356                 screen_save();
357
358                 while(!tval)
359                 {
360 #ifdef JP
361                         prt(format(" %s 杖", (menu_line == 1) ? "》" : "  "), 2, 14);
362                         prt(format(" %s 魔法棒", (menu_line == 2) ? "》" : "  "), 3, 14);
363                         prt(format(" %s ロッド", (menu_line == 3) ? "》" : "  "), 4, 14);
364 #else
365                         prt(format(" %s staff", (menu_line == 1) ? "> " : "  "), 2, 14);
366                         prt(format(" %s wand", (menu_line == 2) ? "> " : "  "), 3, 14);
367                         prt(format(" %s rod", (menu_line == 3) ? "> " : "  "), 4, 14);
368 #endif
369
370                         if (only_browse) prt(_("どの種類の魔法を見ますか?", "Which type of magic do you browse?"), 0, 0);
371                         else prt(_("どの種類の魔法を使いますか?", "Which type of magic do you use?"), 0, 0);
372
373                         choice = inkey();
374                         switch(choice)
375                         {
376                         case ESCAPE:
377                         case 'z':
378                         case 'Z':
379                                 screen_load();
380                                 return -1;
381                         case '2':
382                         case 'j':
383                         case 'J':
384                                 menu_line++;
385                                 break;
386                         case '8':
387                         case 'k':
388                         case 'K':
389                                 menu_line+= 2;
390                                 break;
391                         case '\r':
392                         case 'x':
393                         case 'X':
394                                 ext = (menu_line-1)*EATER_EXT;
395                                 if (menu_line == 1) tval = TV_STAFF;
396                                 else if (menu_line == 2) tval = TV_WAND;
397                                 else tval = TV_ROD;
398                                 break;
399                         }
400                         if (menu_line > 3) menu_line -= 3;
401                 }
402                 screen_load();
403         }
404         else
405         {
406         while (TRUE)
407         {
408                 if (!get_com(_("[A] 杖, [B] 魔法棒, [C] ロッド:", "[A] staff, [B] wand, [C] rod:"), &choice, TRUE))
409                 {
410                         return -1;
411                 }
412                 if (choice == 'A' || choice == 'a')
413                 {
414                         ext = 0;
415                         tval = TV_STAFF;
416                         break;
417                 }
418                 if (choice == 'B' || choice == 'b')
419                 {
420                         ext = EATER_EXT;
421                         tval = TV_WAND;
422                         break;
423                 }
424                 if (choice == 'C' || choice == 'c')
425                 {
426                         ext = EATER_EXT*2;
427                         tval = TV_ROD;
428                         break;
429                 }
430         }
431         }
432         for (i = ext; i < ext + EATER_EXT; i++)
433         {
434                 if (p_ptr->magic_num2[i])
435                 {
436                         if (use_menu) menu_line = i-ext+1;
437                         break;
438                 }
439         }
440         if (i == ext+EATER_EXT)
441         {
442                 msg_print(_("その種類の魔法は覚えていない!", "You don't have that type of magic!"));
443                 return -1;
444         }
445
446         /* Nothing chosen yet */
447         flag = FALSE;
448
449         /* Build a prompt */
450         if (only_browse) strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの魔力を見ますか?",
451                                                                                         "(*=List, ESC=exit) Browse which power? "));
452         else strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの魔力を使いますか?",
453                                                                 "(*=List, ESC=exit) Use which power? "));
454         
455         /* Save the screen */
456         screen_save();
457
458         request_list = always_show_list;
459
460         /* Get a spell from the user */
461         while (!flag)
462         {
463                 /* Show the list */
464                 if (request_list || use_menu)
465                 {
466                         byte y, x = 0;
467                         OBJECT_SUBTYPE_VALUE ctr;
468                         PERCENTAGE chance;
469                         IDX k_idx;
470                         char dummy[80];
471                         POSITION x1, y1;
472                         int level;
473                         byte col;
474
475                         strcpy(dummy, "");
476
477                         for (y = 1; y < 20; y++)
478                                 prt("", y, x);
479
480                         y = 1;
481
482                         /* Print header(s) */
483 #ifdef JP
484                         prt(format("                           %s 失率                           %s 失率", (tval == TV_ROD ? "  状態  " : "使用回数"), (tval == TV_ROD ? "  状態  " : "使用回数")), y++, x);
485 #else
486                         prt(format("                           %s Fail                           %s Fail", (tval == TV_ROD ? "  Stat  " : " Charges"), (tval == TV_ROD ? "  Stat  " : " Charges")), y++, x);
487 #endif
488
489                         /* Print list */
490                         for (ctr = 0; ctr < EATER_EXT; ctr++)
491                         {
492                                 if (!p_ptr->magic_num2[ctr+ext]) continue;
493
494                                 k_idx = lookup_kind(tval, ctr);
495
496                                 if (use_menu)
497                                 {
498                                         if (ctr == (menu_line-1))
499                                                 strcpy(dummy, _("》", "> "));
500                                         else
501                                                 strcpy(dummy, "  ");
502                                 }
503                                 /* letter/number for power selection */
504                                 else
505                                 {
506                                         char letter;
507                                         if (ctr < 26)
508                                                 letter = I2A(ctr);
509                                         else
510                                                 letter = '0' + ctr - 26;
511                                         sprintf(dummy, "%c)",letter);
512                                 }
513                                 x1 = ((ctr < EATER_EXT/2) ? x : x + 40);
514                                 y1 = ((ctr < EATER_EXT/2) ? y + ctr : y + ctr - EATER_EXT/2);
515                                 level = (tval == TV_ROD ? k_info[k_idx].level * 5 / 6 - 5 : k_info[k_idx].level);
516                                 chance = level * 4 / 5 + 20;
517                                 chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
518                                 level /= 2;
519                                 if (p_ptr->lev > level)
520                                 {
521                                         chance -= 3 * (p_ptr->lev - level);
522                                 }
523                                 chance = mod_spell_chance_1(chance);
524                                 chance = MAX(chance, adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]);
525                                 /* Stunning makes spells harder */
526                                 if (p_ptr->stun > 50) chance += 25;
527                                 else if (p_ptr->stun) chance += 15;
528
529                                 if (chance > 95) chance = 95;
530
531                                 chance = mod_spell_chance_2(chance);
532
533                                 col = TERM_WHITE;
534
535                                 if (k_idx)
536                                 {
537                                         if (tval == TV_ROD)
538                                         {
539                                                 strcat(dummy, format(
540                                                                _(" %-22.22s 充填:%2d/%2d%3d%%", " %-22.22s   (%2d/%2d) %3d%%"),
541                                                                k_name + k_info[k_idx].name, 
542                                                                p_ptr->magic_num1[ctr+ext] ? 
543                                                                (p_ptr->magic_num1[ctr+ext] - 1) / (EATER_ROD_CHARGE * k_info[k_idx].pval) +1 : 0, 
544                                                                p_ptr->magic_num2[ctr+ext], chance));
545                                                 if (p_ptr->magic_num1[ctr+ext] > k_info[k_idx].pval * (p_ptr->magic_num2[ctr+ext]-1) * EATER_ROD_CHARGE) col = TERM_RED;
546                                         }
547                                         else
548                                         {
549                                                 strcat(dummy, format(" %-22.22s    %2d/%2d %3d%%", k_name + k_info[k_idx].name, (s16b)(p_ptr->magic_num1[ctr+ext]/EATER_CHARGE), p_ptr->magic_num2[ctr+ext], chance));
550                                                 if (p_ptr->magic_num1[ctr+ext] < EATER_CHARGE) col = TERM_RED;
551                                         }
552                                 }
553                                 else
554                                         strcpy(dummy, "");
555                                 c_prt(col, dummy, y1, x1);
556                         }
557                 }
558
559                 if (!get_com(out_val, &choice, FALSE)) break;
560
561                 if (use_menu && choice != ' ')
562                 {
563                         switch (choice)
564                         {
565                                 case '0':
566                                 {
567                                         screen_load();
568                                         return 0;
569                                 }
570
571                                 case '8':
572                                 case 'k':
573                                 case 'K':
574                                 {
575                                         do
576                                         {
577                                                 menu_line += EATER_EXT - 1;
578                                                 if (menu_line > EATER_EXT) menu_line -= EATER_EXT;
579                                         } while(!p_ptr->magic_num2[menu_line+ext-1]);
580                                         break;
581                                 }
582
583                                 case '2':
584                                 case 'j':
585                                 case 'J':
586                                 {
587                                         do
588                                         {
589                                                 menu_line++;
590                                                 if (menu_line > EATER_EXT) menu_line -= EATER_EXT;
591                                         } while(!p_ptr->magic_num2[menu_line+ext-1]);
592                                         break;
593                                 }
594
595                                 case '4':
596                                 case 'h':
597                                 case 'H':
598                                 case '6':
599                                 case 'l':
600                                 case 'L':
601                                 {
602                                         bool reverse = FALSE;
603                                         if ((choice == '4') || (choice == 'h') || (choice == 'H')) reverse = TRUE;
604                                         if (menu_line > EATER_EXT/2)
605                                         {
606                                                 menu_line -= EATER_EXT/2;
607                                                 reverse = TRUE;
608                                         }
609                                         else menu_line+=EATER_EXT/2;
610                                         while(!p_ptr->magic_num2[menu_line+ext-1])
611                                         {
612                                                 if (reverse)
613                                                 {
614                                                         menu_line--;
615                                                         if (menu_line < 2) reverse = FALSE;
616                                                 }
617                                                 else
618                                                 {
619                                                         menu_line++;
620                                                         if (menu_line > EATER_EXT-1) reverse = TRUE;
621                                                 }
622                                         }
623                                         break;
624                                 }
625
626                                 case 'x':
627                                 case 'X':
628                                 case '\r':
629                                 {
630                                         i = menu_line - 1;
631                                         ask = FALSE;
632                                         break;
633                                 }
634                         }
635                 }
636
637                 /* Request redraw */
638                 if (use_menu && ask) continue;
639
640                 /* Request redraw */
641                 if (!use_menu && ((choice == ' ') || (choice == '*') || (choice == '?')))
642                 {
643                         /* Hide the list */
644                         if (request_list)
645                         {
646                                 /* Hide list */
647                                 request_list = FALSE;
648                                 
649                                 /* Restore the screen */
650                                 screen_load();
651                                 screen_save();
652                         }
653                         else
654                                 request_list = TRUE;
655
656                         /* Redo asking */
657                         continue;
658                 }
659
660                 if (!use_menu)
661                 {
662                         if (isalpha(choice))
663                         {
664                                 /* Note verify */
665                                 ask = (isupper(choice));
666
667                                 /* Lowercase */
668                                 if (ask) choice = (char)tolower(choice);
669
670                                 /* Extract request */
671                                 i = (islower(choice) ? A2I(choice) : -1);
672                         }
673                         else
674                         {
675                                 ask = FALSE; /* Can't uppercase digits */
676
677                                 i = choice - '0' + 26;
678                         }
679                 }
680
681                 /* Totally Illegal */
682                 if ((i < 0) || (i > EATER_EXT) || !p_ptr->magic_num2[i+ext])
683                 {
684                         bell();
685                         continue;
686                 }
687
688                 if (!only_browse)
689                 {
690                         /* Verify it */
691                         if (ask)
692                         {
693                                 char tmp_val[160];
694
695                                 /* Prompt */
696                                 (void) strnfmt(tmp_val, 78, _("%sを使いますか? ", "Use %s?"), k_name + k_info[lookup_kind(tval ,i)].name);
697
698                                 /* Belay that order */
699                                 if (!get_check(tmp_val)) continue;
700                         }
701                         if (tval == TV_ROD)
702                         {
703                                 if (p_ptr->magic_num1[ext+i]  > k_info[lookup_kind(tval, i)].pval * (p_ptr->magic_num2[ext+i] - 1) * EATER_ROD_CHARGE)
704                                 {
705                                         msg_print(_("その魔法はまだ充填している最中だ。", "The magic are still charging."));
706                                         msg_print(NULL);
707                                         if (use_menu) ask = TRUE;
708                                         continue;
709                                 }
710                         }
711                         else
712                         {
713                                 if (p_ptr->magic_num1[ext+i] < EATER_CHARGE)
714                                 {
715                                         msg_print(_("その魔法は使用回数が切れている。", "The magic has no charges left."));
716                                         msg_print(NULL);
717                                         if (use_menu) ask = TRUE;
718                                         continue;
719                                 }
720                         }
721                 }
722
723                 /* Browse */
724                 else
725                 {
726                         int line, j;
727                         char temp[70 * 20];
728
729                         /* Clear lines, position cursor  (really should use strlen here) */
730                         Term_erase(7, 23, 255);
731                         Term_erase(7, 22, 255);
732                         Term_erase(7, 21, 255);
733                         Term_erase(7, 20, 255);
734
735                         roff_to_buf(k_text + k_info[lookup_kind(tval, i)].text, 62, temp, sizeof(temp));
736                         for (j = 0, line = 21; temp[j]; j += 1 + strlen(&temp[j]))
737                         {
738                                 prt(&temp[j], line, 10);
739                                 line++;
740                         }
741
742                         continue;
743                 }
744
745                 /* Stop the loop */
746                 flag = TRUE;
747         }
748
749         /* Restore the screen */
750         screen_load();
751
752         if (!flag) return -1;
753
754 #ifdef ALLOW_REPEAT
755         repeat_push(ext+i);
756 #endif /* ALLOW_REPEAT */
757         return ext+i;
758 }
759
760
761 /*!
762  * @brief 取り込んだ魔力を利用するコマンドのメインルーチン /
763  * Use eaten rod, wand or staff
764  * @param only_browse 閲覧するだけならばTRUE
765  * @param powerful 強力発動中の処理ならばTRUE
766  * @return 実際にコマンドを実行したならばTRUEを返す。
767  */
768 bool do_cmd_magic_eater(bool only_browse, bool powerful)
769 {
770         OBJECT_SUBTYPE_VALUE item;
771         PERCENTAGE chance;
772         DEPTH level;
773         IDX k_idx;
774         OBJECT_TYPE_VALUE tval;
775         OBJECT_SUBTYPE_VALUE sval;
776         bool use_charge = TRUE;
777
778         /* Not when confused */
779         if (!only_browse && p_ptr->confused)
780         {
781                 msg_print(_("混乱していて唱えられない!", "You are too confused!"));
782                 return FALSE;
783         }
784
785         item = select_magic_eater(only_browse);
786         if (item == -1)
787         {
788                 p_ptr->energy_use = 0;
789                 return FALSE;
790         }
791         if (item >= EATER_EXT*2) {tval = TV_ROD;sval = item - EATER_EXT*2;}
792         else if (item >= EATER_EXT) {tval = TV_WAND;sval = item - EATER_EXT;}
793         else {tval = TV_STAFF; sval = item;}
794         k_idx = lookup_kind(tval, sval);
795
796         level = (tval == TV_ROD ? k_info[k_idx].level * 5 / 6 - 5 : k_info[k_idx].level);
797         chance = level * 4 / 5 + 20;
798         chance -= 3 * (adj_mag_stat[p_ptr->stat_ind[mp_ptr->spell_stat]] - 1);
799         level /= 2;
800         if (p_ptr->lev > level)
801         {
802                 chance -= 3 * (p_ptr->lev - level);
803         }
804         chance = mod_spell_chance_1(chance);
805         chance = MAX(chance, adj_mag_fail[p_ptr->stat_ind[mp_ptr->spell_stat]]);
806         /* Stunning makes spells harder */
807         if (p_ptr->stun > 50) chance += 25;
808         else if (p_ptr->stun) chance += 15;
809
810         if (chance > 95) chance = 95;
811
812         chance = mod_spell_chance_2(chance);
813
814         if (randint0(100) < chance)
815         {
816                 if (flush_failure) flush();
817                 
818                 msg_print(_("呪文をうまく唱えられなかった!", "You failed to get the magic off!"));
819                 sound(SOUND_FAIL);
820                 if (randint1(100) >= chance)
821                         chg_virtue(V_CHANCE,-1);
822                 p_ptr->energy_use = 100;
823
824                 return TRUE;
825         }
826         else
827         {
828                 int dir = 0;
829
830                 if (tval == TV_ROD)
831                 {
832                         if ((sval >= SV_ROD_MIN_DIRECTION) && (sval != SV_ROD_HAVOC) && (sval != SV_ROD_AGGRAVATE) && (sval != SV_ROD_PESTICIDE))
833                                 if (!get_aim_dir(&dir)) return FALSE;
834                         rod_effect(sval, dir, &use_charge, powerful, TRUE);
835                         if (!use_charge) return FALSE;
836                 }
837                 else if (tval == TV_WAND)
838                 {
839                         if (!get_aim_dir(&dir)) return FALSE;
840                         wand_effect(sval, dir, powerful, TRUE);
841                 }
842                 else
843                 {
844                         staff_effect(sval, &use_charge, powerful, TRUE, TRUE);
845                         if (!use_charge) return FALSE;
846                 }
847                 if (randint1(100) < chance)
848                         chg_virtue(V_CHANCE,1);
849         }
850         p_ptr->energy_use = 100;
851         if (tval == TV_ROD) p_ptr->magic_num1[item] += k_info[k_idx].pval * EATER_ROD_CHARGE;
852         else p_ptr->magic_num1[item] -= EATER_CHARGE;
853
854         return TRUE;
855 }