OSDN Git Service

[Refactor] #37353 コメント整理。 / Refactor comments.
[hengband/hengband.git] / src / cmd5.c
1 /*!
2  *  @file cmd5.c
3  *  @brief プレイヤーの魔法に関するコマンドの実装 / Spell/Prayer commands
4  *  @date 2014/01/02
5  *  @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  *
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  */
12
13
14 #include "angband.h"
15
16 /*!
17  * @brief 領域魔法に応じて技能の名称を返す。
18  * @param tval 魔法書のtval
19  * @return 領域魔法の技能名称を保管した文字列ポインタ
20  */
21 cptr spell_category_name(OBJECT_TYPE_VALUE tval)
22 {
23         switch (tval)
24         {
25         case TV_HISSATSU_BOOK:
26                 return _("必殺技", "art");
27         case TV_LIFE_BOOK:
28                 return _("祈り", "prayer");
29         case TV_MUSIC_BOOK:
30                 return _("歌", "song");
31         default:
32                 return _("呪文", "spell");
33         }
34 }
35
36
37 bool select_the_force = FALSE;
38
39 /*!
40  * @brief 領域魔法の閲覧、学習、使用選択するインターフェイス処理
41  * Allow user to choose a spell/prayer from the given book.
42  * @param sn 選択した魔法IDを返す参照ポインタ
43  * @param prompt 魔法を利用する際の動詞表記
44  * @param sval 魔道書のsval
45  * @param learned 閲覧/使用選択ならばTRUE、学習処理ならFALSE
46  * @param use_realm 魔法領域ID
47  * @return
48  * <pre>
49  * If a valid spell is chosen, saves it in '*sn' and returns TRUE
50  * If the user hits escape, returns FALSE, and set '*sn' to -1
51  * If there are no legal choices, returns FALSE, and sets '*sn' to -2
52  * The "prompt" should be "cast", "recite", or "study"
53  * The "known" should be TRUE for cast/pray, FALSE for study
54  * </pre>
55  */
56 static int get_spell(SPELL_IDX *sn, cptr prompt, OBJECT_SUBTYPE_VALUE sval, bool learned, REALM_IDX use_realm)
57 {
58         int         i;
59         SPELL_IDX   spell = -1;
60         int         num = 0;
61         int         ask = TRUE;
62         MANA_POINT  need_mana;
63         SPELL_IDX   spells[64];
64         bool        flag, redraw, okay;
65         char        choice;
66         const magic_type  *s_ptr;
67         char        out_val[160];
68         cptr        p;
69         COMMAND_CODE code;
70 #ifdef JP
71         char jverb_buf[128];
72 #endif
73         int menu_line = (use_menu ? 1 : 0);
74
75         /* Get the spell, if available */
76         if (repeat_pull(&code))
77         {
78                 *sn = (SPELL_IDX)code;
79                 /* Verify the spell */
80                 if (spell_okay(*sn, learned, FALSE, use_realm))
81                 {
82                         /* Success */
83                         return (TRUE);
84                 }
85         }
86
87         p = spell_category_name(mp_ptr->spell_book);
88
89         /* Extract spells */
90         for (spell = 0; spell < 32; spell++)
91         {
92                 /* Check for this spell */
93                 if ((fake_spell_flags[sval] & (1L << spell)))
94                 {
95                         /* Collect this spell */
96                         spells[num++] = spell;
97                 }
98         }
99
100         /* Assume no usable spells */
101         okay = FALSE;
102
103         /* Assume no spells available */
104         (*sn) = -2;
105
106         /* Check for "okay" spells */
107         for (i = 0; i < num; i++)
108         {
109                 /* Look for "okay" spells */
110                 if (spell_okay(spells[i], learned, FALSE, use_realm)) okay = TRUE;
111         }
112
113         /* No "okay" spells */
114         if (!okay) return (FALSE);
115         if (((use_realm) != p_ptr->realm1) && ((use_realm) != p_ptr->realm2) && (p_ptr->pclass != CLASS_SORCERER) && (p_ptr->pclass != CLASS_RED_MAGE)) return FALSE;
116         if (((p_ptr->pclass == CLASS_SORCERER) || (p_ptr->pclass == CLASS_RED_MAGE)) && !is_magic(use_realm)) return FALSE;
117         if ((p_ptr->pclass == CLASS_RED_MAGE) && ((use_realm) != REALM_ARCANE) && (sval > 1)) return FALSE;
118
119         /* Assume cancelled */
120         *sn = (-1);
121
122         /* Nothing chosen yet */
123         flag = FALSE;
124
125         /* No redraw yet */
126         redraw = FALSE;
127
128         p_ptr->window |= (PW_SPELL);
129         handle_stuff();
130
131         /* Build a prompt (accept all spells) */
132 #ifdef JP
133         jverb( prompt, jverb_buf, JVERB_AND );
134         (void) strnfmt(out_val, 78, "(%^s:%c-%c, '*'で一覧, ESCで中断) どの%sを%^sますか? ",
135                 p, I2A(0), I2A(num - 1), p, jverb_buf );
136 #else
137         (void)strnfmt(out_val, 78, "(%^ss %c-%c, *=List, ESC=exit) %^s which %s? ",
138                 p, I2A(0), I2A(num - 1), prompt, p);
139 #endif
140
141         /* Get a spell from the user */
142
143         choice = (always_show_list || use_menu) ? ESCAPE : 1;
144         while (!flag)
145         {
146                 if (choice == ESCAPE) choice = ' '; 
147                 else if (!get_com(out_val, &choice, TRUE))break;
148
149                 if (use_menu && choice != ' ')
150                 {
151                         switch (choice)
152                         {
153                                 case '0':
154                                 {
155                                         screen_load();
156                                         return FALSE;
157                                 }
158
159                                 case '8':
160                                 case 'k':
161                                 case 'K':
162                                 {
163                                         menu_line += (num - 1);
164                                         break;
165                                 }
166
167                                 case '2':
168                                 case 'j':
169                                 case 'J':
170                                 {
171                                         menu_line++;
172                                         break;
173                                 }
174
175                                 case 'x':
176                                 case 'X':
177                                 case '\r':
178                                 case '\n':
179                                 {
180                                         i = menu_line - 1;
181                                         ask = FALSE;
182                                         break;
183                                 }
184                         }
185                         if (menu_line > num) menu_line -= num;
186                         /* Display a list of spells */
187                         print_spells(menu_line, spells, num, 1, 15, use_realm);
188                         if (ask) continue;
189                 }
190                 else
191                 {
192                         /* Request redraw */
193                         if ((choice == ' ') || (choice == '*') || (choice == '?'))
194                         {
195                                 /* Show the list */
196                                 if (!redraw)
197                                 {
198                                         /* Show list */
199                                         redraw = TRUE;
200                                         screen_save();
201
202                                         /* Display a list of spells */
203                                         print_spells(menu_line, spells, num, 1, 15, use_realm);
204                                 }
205
206                                 /* Hide the list */
207                                 else
208                                 {
209                                         if (use_menu) continue;
210
211                                         /* Hide list */
212                                         redraw = FALSE;
213                                         screen_load();
214                                 }
215
216                                 /* Redo asking */
217                                 continue;
218                         }
219
220
221                         /* Note verify */
222                         ask = (isupper(choice));
223
224                         /* Lowercase */
225                         if (ask) choice = (char)tolower(choice);
226
227                         /* Extract request */
228                         i = (islower(choice) ? A2I(choice) : -1);
229                 }
230
231                 /* Totally Illegal */
232                 if ((i < 0) || (i >= num))
233                 {
234                         bell();
235                         continue;
236                 }
237
238                 /* Save the spell index */
239                 spell = spells[i];
240
241                 /* Require "okay" spells */
242                 if (!spell_okay(spell, learned, FALSE, use_realm))
243                 {
244                         bell();
245 #ifdef JP
246                         msg_format("その%sを%sことはできません。", p, prompt);
247 #else
248                         msg_format("You may not %s that %s.", prompt, p);
249 #endif
250
251                         continue;
252                 }
253
254                 /* Verify it */
255                 if (ask)
256                 {
257                         char tmp_val[160];
258
259                         /* Access the spell */
260                         if (!is_magic(use_realm))
261                         {
262                                 s_ptr = &technic_info[use_realm - MIN_TECHNIC][spell];
263                         }
264                         else
265                         {
266                                 s_ptr = &mp_ptr->info[use_realm - 1][spell];
267                         }
268
269                         /* Extract mana consumption rate */
270                         if (use_realm == REALM_HISSATSU)
271                         {
272                                 need_mana = s_ptr->smana;
273                         }
274                         else
275                         {
276                                 need_mana = mod_need_mana(s_ptr->smana, spell, use_realm);
277                         }
278
279                         /* Prompt */
280 #ifdef JP
281                         jverb( prompt, jverb_buf, JVERB_AND );
282                         /* 英日切り替え機能に対応 */
283                         (void) strnfmt(tmp_val, 78, "%s(MP%d, 失敗率%d%%)を%sますか? ",
284                                 do_spell(use_realm, spell, SPELL_NAME), need_mana,
285                                        spell_chance(spell, use_realm),jverb_buf);
286 #else
287                         (void)strnfmt(tmp_val, 78, "%^s %s (%d mana, %d%% fail)? ",
288                                 prompt, do_spell(use_realm, spell, SPELL_NAME), need_mana,
289                                 spell_chance(spell, use_realm));
290 #endif
291
292
293                         /* Belay that order */
294                         if (!get_check(tmp_val)) continue;
295                 }
296
297                 /* Stop the loop */
298                 flag = TRUE;
299         }
300
301         if (redraw) screen_load();
302
303         p_ptr->window |= (PW_SPELL);
304         handle_stuff();
305
306         /* Abort if needed */
307         if (!flag) return FALSE;
308
309         /* Save the choice */
310         (*sn) = spell;
311
312         repeat_push((COMMAND_CODE)spell);
313
314         /* Success */
315         return TRUE;
316 }
317
318 /*!
319  * @brief オブジェクトがプレイヤーが使用可能な魔道書かどうかを判定する
320  * @param o_ptr 判定したいオブ会ジェクトの構造体参照ポインタ
321  * @return 学習できる魔道書ならばTRUEを返す
322  */
323 static bool item_tester_learn_spell(object_type *o_ptr)
324 {
325         s32b choices = realm_choices2[p_ptr->pclass];
326
327         if (p_ptr->pclass == CLASS_PRIEST)
328         {
329                 if (is_good_realm(p_ptr->realm1))
330                 {
331                         choices &= ~(CH_DEATH | CH_DAEMON);
332                 }
333                 else
334                 {
335                         choices &= ~(CH_LIFE | CH_CRUSADE);
336                 }
337         }
338
339         if ((o_ptr->tval < TV_LIFE_BOOK) || (o_ptr->tval > (TV_LIFE_BOOK + MAX_REALM - 1))) return (FALSE);
340         if ((o_ptr->tval == TV_MUSIC_BOOK) && (p_ptr->pclass == CLASS_BARD)) return (TRUE);
341         else if (!is_magic(tval2realm(o_ptr->tval))) return FALSE;
342         if ((REALM1_BOOK == o_ptr->tval) || (REALM2_BOOK == o_ptr->tval)) return (TRUE);
343         if (choices & (0x0001 << (tval2realm(o_ptr->tval) - 1))) return (TRUE);
344         return (FALSE);
345 }
346
347 /*!
348  * @brief プレイヤーが魔道書を一冊も持っていないかを判定する
349  * @return 魔道書を一冊も持っていないならTRUEを返す
350  */
351 static bool player_has_no_spellbooks(void)
352 {
353         int         i;
354         object_type *o_ptr;
355
356         for (i = 0; i < INVEN_PACK; i++)
357         {
358                 o_ptr = &inventory[i];
359                 if (o_ptr->k_idx && check_book_realm(o_ptr->tval, o_ptr->sval)) return FALSE;
360         }
361
362         for (i = cave[p_ptr->y][p_ptr->x].o_idx; i; i = o_ptr->next_o_idx)
363         {
364                 o_ptr = &o_list[i];
365                 if (o_ptr->k_idx && (o_ptr->marked & OM_FOUND) && check_book_realm(o_ptr->tval, o_ptr->sval)) return FALSE;
366         }
367
368         return TRUE;
369 }
370
371 /*!
372  * @brief プレイヤーの職業が練気術師の時、領域魔法と練気術を切り換える処理のインターフェイス
373  * @param browse_only 魔法と技能の閲覧を行うならばTRUE
374  * @return 魔道書を一冊も持っていないならTRUEを返す
375  */
376 static void confirm_use_force(bool browse_only)
377 {
378         char which;
379         COMMAND_CODE code;
380
381         /* Get the item index */
382         if (repeat_pull(&code) && (code == INVEN_FORCE))
383         {
384                 browse_only ? do_cmd_mind_browse() : do_cmd_mind();
385                 return;
386         }
387
388         /* Show the prompt */
389         prt(_("('w'練気術, ESC) 'w'かESCを押してください。 ", "(w for the Force, ESC) Hit 'w' or ESC. "), 0, 0);
390
391         while (1)
392         {
393                 /* Get a key */
394                 which = inkey();
395
396                 if (which == ESCAPE) break;
397                 else if (which == 'w')
398                 {
399
400                         repeat_push(INVEN_FORCE);
401
402                         break;
403                 }
404         }
405
406         /* Clear the prompt line */
407         prt("", 0, 0);
408
409         if (which == 'w')
410         {
411                 browse_only ? do_cmd_mind_browse() : do_cmd_mind();
412         }
413 }
414
415
416 /*!
417  * @brief プレイヤーの魔法と技能を閲覧するコマンドのメインルーチン /
418  * Peruse the spells/prayers in a book
419  * @return なし
420  * @details
421  * <pre>
422  * Note that *all* spells in the book are listed
423  *
424  * Note that browsing is allowed while confused or blind,
425  * and in the dark, primarily to allow browsing in stores.
426  * </pre>
427  */
428 void do_cmd_browse(void)
429 {
430         OBJECT_IDX item;
431         OBJECT_SUBTYPE_VALUE sval;
432         REALM_IDX use_realm = 0;
433         int j, line;
434         SPELL_IDX spell = -1;
435         int num = 0;
436
437         SPELL_IDX spells[64];
438         char temp[62*4];
439
440         object_type     *o_ptr;
441
442         cptr q, s;
443
444         /* Warriors are illiterate */
445         if (!(p_ptr->realm1 || p_ptr->realm2) && (p_ptr->pclass != CLASS_SORCERER) && (p_ptr->pclass != CLASS_RED_MAGE))
446         {
447                 msg_print(_("本を読むことができない!", "You cannot read books!"));
448                 return;
449         }
450
451         if (p_ptr->special_defense & KATA_MUSOU)
452         {
453                 set_action(ACTION_NONE);
454         }
455
456         if (p_ptr->pclass == CLASS_FORCETRAINER)
457         {
458                 if (player_has_no_spellbooks())
459                 {
460                         confirm_use_force(TRUE);
461                         return;
462                 }
463                 select_the_force = TRUE;
464         }
465
466         /* Restrict choices to "useful" books */
467         if (p_ptr->realm2 == REALM_NONE) item_tester_tval = mp_ptr->spell_book;
468         else item_tester_hook = item_tester_learn_spell;
469
470         q = _("どの本を読みますか? ", "Browse which book? ");
471         s = _("読める本がない。", "You have no books that you can read.");
472
473         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR)))
474         {
475                 select_the_force = FALSE;
476                 return;
477         }
478         select_the_force = FALSE;
479
480         if (item == INVEN_FORCE) /* the_force */
481         {
482                 do_cmd_mind_browse();
483                 return;
484         }
485
486         /* Get the item (in the pack) */
487         else if (item >= 0)
488         {
489                 o_ptr = &inventory[item];
490         }
491
492         /* Get the item (on the floor) */
493         else
494         {
495                 o_ptr = &o_list[0 - item];
496         }
497
498         /* Access the item's sval */
499         sval = o_ptr->sval;
500
501         use_realm = tval2realm(o_ptr->tval);
502
503         /* Track the object kind */
504         object_kind_track(o_ptr->k_idx);
505         handle_stuff();
506
507
508         /* Extract spells */
509         for (spell = 0; spell < 32; spell++)
510         {
511                 /* Check for this spell */
512                 if ((fake_spell_flags[sval] & (1L << spell)))
513                 {
514                         /* Collect this spell */
515                         spells[num++] = spell;
516                 }
517         }
518
519         screen_save();
520
521         /* Clear the top line */
522         prt("", 0, 0);
523
524         /* Keep browsing spells.  Exit browsing on cancel. */
525         while(TRUE)
526         {
527                 /* Ask for a spell, allow cancel */
528                 if (!get_spell(&spell, _("読む", "browse"), o_ptr->sval, TRUE, use_realm))
529                 {
530                         /* If cancelled, leave immediately. */
531                         if (spell == -1) break;
532
533                         /* Display a list of spells */
534                         print_spells(0, spells, num, 1, 15, use_realm);
535
536                         /* Notify that there's nothing to see, and wait. */
537                         if (use_realm == REALM_HISSATSU)
538                                 prt(_("読める技がない。", "No techniques to browse."), 0, 0);
539                         else
540                                 prt(_("読める呪文がない。", "No spells to browse."), 0, 0);
541                         (void)inkey();
542
543                         screen_load();
544
545                         return;
546                 }
547
548                 /* Clear lines, position cursor  (really should use strlen here) */
549                 Term_erase(14, 14, 255);
550                 Term_erase(14, 13, 255);
551                 Term_erase(14, 12, 255);
552                 Term_erase(14, 11, 255);
553
554                 roff_to_buf(do_spell(use_realm, spell, SPELL_DESC), 62, temp, sizeof(temp));
555
556                 for (j = 0, line = 11; temp[j]; j += 1 + strlen(&temp[j]))
557                 {
558                         prt(&temp[j], line, 15);
559                         line++;
560                 }
561         }
562         screen_load();
563 }
564
565 /*!
566  * @brief プレイヤーの第二魔法領域を変更する /
567  * @param next_realm 変更先の魔法領域ID
568  * @return なし
569  */
570 static void change_realm2(CHARACTER_IDX next_realm)
571 {
572         int i, j = 0;
573         char tmp[80];
574
575         for (i = 0; i < 64; i++)
576         {
577                 p_ptr->spell_order[j] = p_ptr->spell_order[i];
578                 if (p_ptr->spell_order[i] < 32) j++;
579         }
580         for (; j < 64; j++)
581                 p_ptr->spell_order[j] = 99;
582
583         for (i = 32; i < 64; i++)
584         {
585                 p_ptr->spell_exp[i] = SPELL_EXP_UNSKILLED;
586         }
587         p_ptr->spell_learned2 = 0L;
588         p_ptr->spell_worked2 = 0L;
589         p_ptr->spell_forgotten2 = 0L;
590
591         sprintf(tmp,_("魔法の領域を%sから%sに変更した。", "change magic realm from %s to %s."), realm_names[p_ptr->realm2], realm_names[next_realm]);
592         do_cmd_write_nikki(NIKKI_BUNSHOU, 0, tmp);
593         p_ptr->old_realm |= 1 << (p_ptr->realm2-1);
594         p_ptr->realm2 = next_realm;
595
596         p_ptr->notice |= (PN_REORDER);
597         p_ptr->update |= (PU_SPELLS);
598         handle_stuff();
599
600         /* Load an autopick preference file */
601         autopick_load_pref(FALSE);
602 }
603
604
605 /*!
606  * @brief 魔法を学習するコマンドのメインルーチン /
607  * Study a book to gain a new spell/prayer
608  * @return なし
609  */
610 void do_cmd_study(void)
611 {
612         int     i;
613         OBJECT_IDX item;
614         OBJECT_SUBTYPE_VALUE sval;
615         int     increment = 0;
616         bool    learned = FALSE;
617
618         /* Spells of realm2 will have an increment of +32 */
619         SPELL_IDX spell = -1;
620
621         cptr p = spell_category_name(mp_ptr->spell_book);
622
623         object_type *o_ptr;
624
625         cptr q, s;
626
627         if (!p_ptr->realm1)
628         {
629                 msg_print(_("本を読むことができない!", "You cannot read books!"));
630                 return;
631         }
632
633         if (p_ptr->blind || no_lite())
634         {
635                 msg_print(_("目が見えない!", "You cannot see!"));
636                 return;
637         }
638
639         if (p_ptr->confused)
640         {
641                 msg_print(_("混乱していて読めない!", "You are too confused!"));
642                 return;
643         }
644
645         if (!(p_ptr->new_spells))
646         {
647                 msg_format(_("新しい%sを覚えることはできない!", "You cannot learn any new %ss!"), p);
648                 return;
649         }
650
651         if (p_ptr->special_defense & KATA_MUSOU)
652         {
653                 set_action(ACTION_NONE);
654         }
655
656 #ifdef JP
657         if( p_ptr->new_spells < 10 ){
658                 msg_format("あと %d つの%sを学べる。", p_ptr->new_spells, p);
659         }else{
660                 msg_format("あと %d 個の%sを学べる。", p_ptr->new_spells, p);
661         }
662 #else
663         msg_format("You can learn %d new %s%s.", p_ptr->new_spells, p,
664                 (p_ptr->new_spells == 1?"":"s"));
665 #endif
666
667         msg_print(NULL);
668
669
670         /* Restrict choices to "useful" books */
671         if (p_ptr->realm2 == REALM_NONE) item_tester_tval = mp_ptr->spell_book;
672         else item_tester_hook = item_tester_learn_spell;
673
674         q = _("どの本から学びますか? ", "Study which book? ");
675         s = _("読める本がない。", "You have no books that you can read.");
676
677         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
678
679         /* Get the item (in the pack) */
680         if (item >= 0)
681         {
682                 o_ptr = &inventory[item];
683         }
684
685         /* Get the item (on the floor) */
686         else
687         {
688                 o_ptr = &o_list[0 - item];
689         }
690
691         /* Access the item's sval */
692         sval = o_ptr->sval;
693
694         if (o_ptr->tval == REALM2_BOOK) increment = 32;
695         else if (o_ptr->tval != REALM1_BOOK)
696         {
697                 if (!get_check(_("本当に魔法の領域を変更しますか?", "Really, change magic realm? "))) return;
698                 change_realm2(tval2realm(o_ptr->tval));
699                 increment = 32;
700         }
701
702         /* Track the object kind */
703         object_kind_track(o_ptr->k_idx);
704         handle_stuff();
705
706         /* Mage -- Learn a selected spell */
707         if (mp_ptr->spell_book != TV_LIFE_BOOK)
708         {
709                 /* Ask for a spell, allow cancel */
710                 if (!get_spell(&spell, _("学ぶ", "study"), sval, FALSE, o_ptr->tval - TV_LIFE_BOOK + 1) && (spell == -1)) return;
711         }
712
713         /* Priest -- Learn a random prayer */
714         else
715         {
716                 int k = 0;
717                 int gift = -1;
718
719                 /* Extract spells */
720                 for (spell = 0; spell < 32; spell++)
721                 {
722                         /* Check spells in the book */
723                         if ((fake_spell_flags[sval] & (1L << spell)))
724                         {
725                                 /* Skip non "okay" prayers */
726                                 if (!spell_okay(spell, FALSE, TRUE,
727                                         (increment ? p_ptr->realm2 : p_ptr->realm1))) continue;
728
729                                 /* Hack -- Prepare the randomizer */
730                                 k++;
731
732                                 /* Hack -- Apply the randomizer */
733                                 if (one_in_(k)) gift = spell;
734                         }
735                 }
736
737                 /* Accept gift */
738                 spell = gift;
739         }
740
741         /* Nothing to study */
742         if (spell < 0)
743         {
744                 msg_format(_("その本には学ぶべき%sがない。", "You cannot learn any %ss in that book."), p);
745
746                 /* Abort */
747                 return;
748         }
749
750         if (increment) spell += increment;
751
752         /* Learn the spell */
753         if (spell < 32)
754         {
755                 if (p_ptr->spell_learned1 & (1L << spell)) learned = TRUE;
756                 else p_ptr->spell_learned1 |= (1L << spell);
757         }
758         else
759         {
760                 if (p_ptr->spell_learned2 & (1L << (spell - 32))) learned = TRUE;
761                 else p_ptr->spell_learned2 |= (1L << (spell - 32));
762         }
763
764         if (learned)
765         {
766                 int max_exp = (spell < 32) ? SPELL_EXP_MASTER : SPELL_EXP_EXPERT;
767                 int old_exp = p_ptr->spell_exp[spell];
768                 int new_rank = EXP_LEVEL_UNSKILLED;
769                 cptr name = do_spell(increment ? p_ptr->realm2 : p_ptr->realm1, spell%32, SPELL_NAME);
770
771                 if (old_exp >= max_exp)
772                 {
773                         msg_format(_("その%sは完全に使いこなせるので学ぶ必要はない。", "You don't need to study this %s anymore."), p);
774                         return;
775                 }
776 #ifdef JP
777                 if (!get_check(format("%sの%sをさらに学びます。よろしいですか?", name, p)))
778 #else
779                 if (!get_check(format("You will study a %s of %s again. Are you sure? ", p, name)))
780 #endif
781                 {
782                         return;
783                 }
784                 else if (old_exp >= SPELL_EXP_EXPERT)
785                 {
786                         p_ptr->spell_exp[spell] = SPELL_EXP_MASTER;
787                         new_rank = EXP_LEVEL_MASTER;
788                 }
789                 else if (old_exp >= SPELL_EXP_SKILLED)
790                 {
791                         if (spell >= 32) p_ptr->spell_exp[spell] = SPELL_EXP_EXPERT;
792                         else p_ptr->spell_exp[spell] += SPELL_EXP_EXPERT - SPELL_EXP_SKILLED;
793                         new_rank = EXP_LEVEL_EXPERT;
794                 }
795                 else if (old_exp >= SPELL_EXP_BEGINNER)
796                 {
797                         p_ptr->spell_exp[spell] = SPELL_EXP_SKILLED + (old_exp - SPELL_EXP_BEGINNER) * 2 / 3;
798                         new_rank = EXP_LEVEL_SKILLED;
799                 }
800                 else
801                 {
802                         p_ptr->spell_exp[spell] = SPELL_EXP_BEGINNER + old_exp / 3;
803                         new_rank = EXP_LEVEL_BEGINNER;
804                 }
805                 msg_format(_("%sの熟練度が%sに上がった。", "Your proficiency of %s is now %s rank."), name, exp_level_str[new_rank]);
806         }
807         else
808         {
809                 /* Find the next open entry in "p_ptr->spell_order[]" */
810                 for (i = 0; i < 64; i++)
811                 {
812                         /* Stop at the first empty space */
813                         if (p_ptr->spell_order[i] == 99) break;
814                 }
815
816                 /* Add the spell to the known list */
817                 p_ptr->spell_order[i++] = spell;
818
819                 /* Mention the result */
820 #ifdef JP
821                 /* 英日切り替え機能に対応 */
822                 if (mp_ptr->spell_book == TV_MUSIC_BOOK)
823                 {
824                         msg_format("%sを学んだ。",
825                                     do_spell(increment ? p_ptr->realm2 : p_ptr->realm1, spell % 32, SPELL_NAME));
826                 }
827                 else
828                 {
829                         msg_format("%sの%sを学んだ。",
830                                     do_spell(increment ? p_ptr->realm2 : p_ptr->realm1, spell % 32, SPELL_NAME) ,p);
831                 }
832 #else
833                 msg_format("You have learned the %s of %s.",
834                         p, do_spell(increment ? p_ptr->realm2 : p_ptr->realm1, spell % 32, SPELL_NAME));
835 #endif
836         }
837
838         p_ptr->energy_use = 100;
839
840         switch (mp_ptr->spell_book)
841         {
842         case TV_LIFE_BOOK:
843                 chg_virtue(V_FAITH, 1);
844                 break;
845         case TV_DEATH_BOOK:
846                 chg_virtue(V_UNLIFE, 1);
847                 break;
848         case TV_NATURE_BOOK:
849                 chg_virtue(V_NATURE, 1);
850                 break;
851         default:
852                 chg_virtue(V_KNOWLEDGE, 1);
853                 break;
854         }
855
856         sound(SOUND_STUDY);
857
858         /* One less spell available */
859         p_ptr->learned_spells++;
860 #
861         /* Update Study */
862         p_ptr->update |= (PU_SPELLS);
863         handle_stuff();
864
865         /* Redraw object recall */
866         p_ptr->window |= (PW_OBJECT);
867 }
868
869
870 /*!
871  * @brief 魔法を詠唱するコマンドのメインルーチン /
872  * Cast a spell
873  * @return なし
874  */
875 void do_cmd_cast(void)
876 {
877         OBJECT_IDX item;
878         OBJECT_SUBTYPE_VALUE sval;
879         SPELL_IDX spell;
880         REALM_IDX realm;
881         int     chance;
882         int     increment = 0;
883         REALM_IDX use_realm;
884         MANA_POINT need_mana;
885
886         cptr prayer;
887         object_type     *o_ptr;
888         const magic_type *s_ptr;
889         cptr q, s;
890
891         bool over_exerted = FALSE;
892
893         /* Require spell ability */
894         if (!p_ptr->realm1 && (p_ptr->pclass != CLASS_SORCERER) && (p_ptr->pclass != CLASS_RED_MAGE))
895         {
896                 msg_print(_("呪文を唱えられない!", "You cannot cast spells!"));
897                 return;
898         }
899
900         /* Require lite */
901         if (p_ptr->blind || no_lite())
902         {
903                 if (p_ptr->pclass == CLASS_FORCETRAINER) confirm_use_force(FALSE);
904                 else
905                 {
906                         msg_print(_("目が見えない!", "You cannot see!"));
907                         flush();
908                 }
909                 return;
910         }
911
912         /* Not when confused */
913         if (p_ptr->confused)
914         {
915                 msg_print(_("混乱していて唱えられない!", "You are too confused!"));
916                 flush();
917                 return;
918         }
919
920         /* Hex */
921         if (p_ptr->realm1 == REALM_HEX)
922         {
923                 if (hex_spell_fully())
924                 {
925                         bool flag = FALSE;
926                         msg_print(_("これ以上新しい呪文を詠唱することはできない。", "Can not spell new spells more."));
927                         flush();
928                         if (p_ptr->lev >= 35) flag = stop_hex_spell();
929                         if (!flag) return;
930                 }
931         }
932
933         if (p_ptr->pclass == CLASS_FORCETRAINER)
934         {
935                 if (player_has_no_spellbooks())
936                 {
937                         confirm_use_force(FALSE);
938                         return;
939                 }
940                 select_the_force = TRUE;
941         }
942
943         prayer = spell_category_name(mp_ptr->spell_book);
944
945         /* Restrict choices to spell books */
946         item_tester_tval = mp_ptr->spell_book;
947
948         q = _("どの呪文書を使いますか? ", "Use which book? ");
949         s = _("呪文書がない!", "You have no spell books!");
950
951         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR)))
952         {
953                 select_the_force = FALSE;
954                 return;
955         }
956         select_the_force = FALSE;
957
958         if (item == INVEN_FORCE) /* the_force */
959         {
960                 do_cmd_mind();
961                 return;
962         }
963
964         /* Get the item (in the pack) */
965         else if (item >= 0)
966         {
967                 o_ptr = &inventory[item];
968         }
969
970         /* Get the item (on the floor) */
971         else
972         {
973                 o_ptr = &o_list[0 - item];
974         }
975
976         /* Access the item's sval */
977         sval = o_ptr->sval;
978
979         if ((p_ptr->pclass != CLASS_SORCERER) && (p_ptr->pclass != CLASS_RED_MAGE) && (o_ptr->tval == REALM2_BOOK)) increment = 32;
980
981
982         /* Track the object kind */
983         object_kind_track(o_ptr->k_idx);
984         handle_stuff();
985
986         if ((p_ptr->pclass == CLASS_SORCERER) || (p_ptr->pclass == CLASS_RED_MAGE))
987                 realm = o_ptr->tval - TV_LIFE_BOOK + 1;
988         else if (increment) realm = p_ptr->realm2;
989         else realm = p_ptr->realm1;
990
991         /* Ask for a spell */
992 #ifdef JP
993         if (!get_spell(&spell, ((mp_ptr->spell_book == TV_LIFE_BOOK) ? "詠唱する" : (mp_ptr->spell_book == TV_MUSIC_BOOK) ? "歌う" : "唱える"), 
994                         sval, TRUE, realm))
995         {
996                 if (spell == -2) msg_format("その本には知っている%sがない。", prayer);
997                 return;
998         }
999 #else
1000         if (!get_spell(&spell, ((mp_ptr->spell_book == TV_LIFE_BOOK) ? "recite" : "cast"),
1001                 sval, TRUE, realm))
1002         {
1003                 if (spell == -2)
1004                         msg_format("You don't know any %ss in that book.", prayer);
1005                 return;
1006         }
1007 #endif
1008
1009
1010         use_realm = tval2realm(o_ptr->tval);
1011
1012         /* Hex */
1013         if (use_realm == REALM_HEX)
1014         {
1015                 if (hex_spelling(spell))
1016                 {
1017                         msg_print(_("その呪文はすでに詠唱中だ。", "You are already casting it."));
1018                         return;
1019                 }
1020         }
1021
1022         if (!is_magic(use_realm))
1023         {
1024                 s_ptr = &technic_info[use_realm - MIN_TECHNIC][spell];
1025         }
1026         else
1027         {
1028                 s_ptr = &mp_ptr->info[realm - 1][spell];
1029         }
1030
1031         /* Extract mana consumption rate */
1032         need_mana = mod_need_mana(s_ptr->smana, spell, realm);
1033
1034         /* Verify "dangerous" spells */
1035         if (need_mana > p_ptr->csp)
1036         {
1037                 if (flush_failure) flush();
1038
1039                 /* Warning */
1040 #ifdef JP
1041                 msg_format("その%sを%sのに十分なマジックポイントがない。",prayer,
1042                          ((mp_ptr->spell_book == TV_LIFE_BOOK) ? "詠唱する" : (mp_ptr->spell_book == TV_LIFE_BOOK) ? "歌う" : "唱える"));
1043 #else
1044                 msg_format("You do not have enough mana to %s this %s.",
1045                         ((mp_ptr->spell_book == TV_LIFE_BOOK) ? "recite" : "cast"),
1046                         prayer);
1047 #endif
1048
1049
1050                 if (!over_exert) return;
1051
1052                 /* Verify */
1053                 if (!get_check_strict(_("それでも挑戦しますか? ", "Attempt it anyway? "), CHECK_OKAY_CANCEL)) return;
1054         }
1055
1056         /* Spell failure chance */
1057         chance = spell_chance(spell, use_realm);
1058
1059         /* Sufficient mana */
1060         if (need_mana <= p_ptr->csp)
1061         {
1062                 /* Use some mana */
1063                 p_ptr->csp -= need_mana;
1064         }
1065         else over_exerted = TRUE;
1066         p_ptr->redraw |= (PR_MANA);
1067
1068         /* Failed spell */
1069         if (randint0(100) < chance)
1070         {
1071                 if (flush_failure) flush();
1072                 
1073                 msg_format(_("%sをうまく唱えられなかった!", "You failed to get the %s off!"), prayer);
1074                 sound(SOUND_FAIL);
1075
1076                 switch (realm)
1077                 {
1078                 case REALM_LIFE:
1079                         if (randint1(100) < chance) chg_virtue(V_VITALITY, -1);
1080                         break;
1081                 case REALM_DEATH:
1082                         if (randint1(100) < chance) chg_virtue(V_UNLIFE, -1);
1083                         break;
1084                 case REALM_NATURE:
1085                         if (randint1(100) < chance) chg_virtue(V_NATURE, -1);
1086                         break;
1087                 case REALM_DAEMON:
1088                         if (randint1(100) < chance) chg_virtue(V_JUSTICE, 1);
1089                         break;
1090                 case REALM_CRUSADE:
1091                         if (randint1(100) < chance) chg_virtue(V_JUSTICE, -1);
1092                         break;
1093                 case REALM_HEX:
1094                         if (randint1(100) < chance) chg_virtue(V_COMPASSION, -1);
1095                         break;
1096                 default:
1097                         if (randint1(100) < chance) chg_virtue(V_KNOWLEDGE, -1);
1098                         break;
1099                 }
1100
1101                 /* Failure casting may activate some side effect */
1102                 do_spell(realm, spell, SPELL_FAIL);
1103
1104
1105                 if ((o_ptr->tval == TV_CHAOS_BOOK) && (randint1(100) < spell))
1106                 {
1107                         msg_print(_("カオス的な効果を発生した!", "You produce a chaotic effect!"));
1108                         wild_magic(spell);
1109                 }
1110                 else if ((o_ptr->tval == TV_DEATH_BOOK) && (randint1(100) < spell))
1111                 {
1112                         if ((sval == 3) && one_in_(2))
1113                         {
1114                                 sanity_blast(0, TRUE);
1115                         }
1116                         else
1117                         {
1118                                 msg_print(_("痛い!", "It hurts!"));
1119                                 take_hit(DAMAGE_LOSELIFE, damroll(o_ptr->sval + 1, 6), _("暗黒魔法の逆流", "a miscast Death spell"), -1);
1120
1121                                 if ((spell > 15) && one_in_(6) && !p_ptr->hold_exp)
1122                                         lose_exp(spell * 250);
1123                         }
1124                 }
1125                 else if ((o_ptr->tval == TV_MUSIC_BOOK) && (randint1(200) < spell))
1126                 {
1127                         msg_print(_("いやな音が響いた", "An infernal sound echoed."));
1128                         aggravate_monsters(0);
1129                 }
1130                 if (randint1(100) >= chance)
1131                         chg_virtue(V_CHANCE,-1);
1132         }
1133
1134         /* Process spell */
1135         else
1136         {
1137                 /* Canceled spells cost neither a turn nor mana */
1138                 if (!do_spell(realm, spell, SPELL_CAST)) return;
1139
1140                 if (randint1(100) < chance)
1141                         chg_virtue(V_CHANCE,1);
1142
1143                 /* A spell was cast */
1144                 if (!(increment ?
1145                     (p_ptr->spell_worked2 & (1L << spell)) :
1146                     (p_ptr->spell_worked1 & (1L << spell)))
1147                     && (p_ptr->pclass != CLASS_SORCERER)
1148                     && (p_ptr->pclass != CLASS_RED_MAGE))
1149                 {
1150                         int e = s_ptr->sexp;
1151
1152                         /* The spell worked */
1153                         if (realm == p_ptr->realm1)
1154                         {
1155                                 p_ptr->spell_worked1 |= (1L << spell);
1156                         }
1157                         else
1158                         {
1159                                 p_ptr->spell_worked2 |= (1L << spell);
1160                         }
1161
1162                         /* Gain experience */
1163                         gain_exp(e * s_ptr->slevel);
1164
1165                         /* Redraw object recall */
1166                         p_ptr->window |= (PW_OBJECT);
1167
1168                         switch (realm)
1169                         {
1170                         case REALM_LIFE:
1171                                 chg_virtue(V_TEMPERANCE, 1);
1172                                 chg_virtue(V_COMPASSION, 1);
1173                                 chg_virtue(V_VITALITY, 1);
1174                                 chg_virtue(V_DILIGENCE, 1);
1175                                 break;
1176                         case REALM_DEATH:
1177                                 chg_virtue(V_UNLIFE, 1);
1178                                 chg_virtue(V_JUSTICE, -1);
1179                                 chg_virtue(V_FAITH, -1);
1180                                 chg_virtue(V_VITALITY, -1);
1181                                 break;
1182                         case REALM_DAEMON:
1183                                 chg_virtue(V_JUSTICE, -1);
1184                                 chg_virtue(V_FAITH, -1);
1185                                 chg_virtue(V_HONOUR, -1);
1186                                 chg_virtue(V_TEMPERANCE, -1);
1187                                 break;
1188                         case REALM_CRUSADE:
1189                                 chg_virtue(V_FAITH, 1);
1190                                 chg_virtue(V_JUSTICE, 1);
1191                                 chg_virtue(V_SACRIFICE, 1);
1192                                 chg_virtue(V_HONOUR, 1);
1193                                 break;
1194                         case REALM_NATURE:
1195                                 chg_virtue(V_NATURE, 1);
1196                                 chg_virtue(V_HARMONY, 1);
1197                                 break;
1198                         case REALM_HEX:
1199                                 chg_virtue(V_JUSTICE, -1);
1200                                 chg_virtue(V_FAITH, -1);
1201                                 chg_virtue(V_HONOUR, -1);
1202                                 chg_virtue(V_COMPASSION, -1);
1203                                 break;
1204                         default:
1205                                 chg_virtue(V_KNOWLEDGE, 1);
1206                                 break;
1207                         }
1208                 }
1209                 switch (realm)
1210                 {
1211                 case REALM_LIFE:
1212                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_TEMPERANCE, 1);
1213                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_COMPASSION, 1);
1214                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_VITALITY, 1);
1215                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_DILIGENCE, 1);
1216                         break;
1217                 case REALM_DEATH:
1218                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_UNLIFE, 1);
1219                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_JUSTICE, -1);
1220                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_FAITH, -1);
1221                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_VITALITY, -1);
1222                         break;
1223                 case REALM_DAEMON:
1224                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_JUSTICE, -1);
1225                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_FAITH, -1);
1226                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_HONOUR, -1);
1227                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_TEMPERANCE, -1);
1228                         break;
1229                 case REALM_CRUSADE:
1230                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_FAITH, 1);
1231                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_JUSTICE, 1);
1232                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_SACRIFICE, 1);
1233                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_HONOUR, 1);
1234                         break;
1235                 case REALM_NATURE:
1236                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_NATURE, 1);
1237                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_HARMONY, 1);
1238                         break;
1239                 case REALM_HEX:
1240                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_JUSTICE, -1);
1241                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_FAITH, -1);
1242                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_HONOUR, -1);
1243                         if (randint1(100 + p_ptr->lev) < need_mana) chg_virtue(V_COMPASSION, -1);
1244                         break;
1245                 }
1246                 if (mp_ptr->spell_xtra & MAGIC_GAIN_EXP)
1247                 {
1248                         s16b cur_exp = p_ptr->spell_exp[(increment ? 32 : 0)+spell];
1249                         s16b exp_gain = 0;
1250
1251                         if (cur_exp < SPELL_EXP_BEGINNER)
1252                                 exp_gain += 60;
1253                         else if (cur_exp < SPELL_EXP_SKILLED)
1254                         {
1255                                 if ((dun_level > 4) && ((dun_level + 10) > p_ptr->lev))
1256                                         exp_gain = 8;
1257                         }
1258                         else if (cur_exp < SPELL_EXP_EXPERT)
1259                         {
1260                                 if (((dun_level + 5) > p_ptr->lev) && ((dun_level + 5) > s_ptr->slevel))
1261                                         exp_gain = 2;
1262                         }
1263                         else if ((cur_exp < SPELL_EXP_MASTER) && !increment)
1264                         {
1265                                 if (((dun_level + 5) > p_ptr->lev) && (dun_level > s_ptr->slevel))
1266                                         exp_gain = 1;
1267                         }
1268                         p_ptr->spell_exp[(increment ? 32 : 0) + spell] += exp_gain;
1269                 }
1270         }
1271
1272         p_ptr->energy_use = 100;
1273
1274
1275         /* Over-exert the player */
1276         if(over_exerted)
1277         {
1278                 int oops = need_mana;
1279
1280                 /* No mana left */
1281                 p_ptr->csp = 0;
1282                 p_ptr->csp_frac = 0;
1283
1284                 msg_print(_("精神を集中しすぎて気を失ってしまった!", "You faint from the effort!"));
1285
1286                 /* Hack -- Bypass free action */
1287                 (void)set_paralyzed(p_ptr->paralyzed + randint1(5 * oops + 1));
1288
1289                 switch (realm)
1290                 {
1291                 case REALM_LIFE:
1292                         chg_virtue(V_VITALITY, -10);
1293                         break;
1294                 case REALM_DEATH:
1295                         chg_virtue(V_UNLIFE, -10);
1296                         break;
1297                 case REALM_DAEMON:
1298                         chg_virtue(V_JUSTICE, 10);
1299                         break;
1300                 case REALM_NATURE:
1301                         chg_virtue(V_NATURE, -10);
1302                         break;
1303                 case REALM_CRUSADE:
1304                         chg_virtue(V_JUSTICE, -10);
1305                         break;
1306                 case REALM_HEX:
1307                         chg_virtue(V_COMPASSION, 10);
1308                         break;
1309                 default:
1310                         chg_virtue(V_KNOWLEDGE, -10);
1311                         break;
1312                 }
1313
1314                 /* Damage CON (possibly permanently) */
1315                 if (randint0(100) < 50)
1316                 {
1317                         bool perm = (randint0(100) < 25);
1318
1319                         msg_print(_("体を悪くしてしまった!", "You have damaged your health!"));
1320
1321                         /* Reduce constitution */
1322                         (void)dec_stat(A_CON, 15 + randint1(10), perm);
1323                 }
1324         }
1325
1326         p_ptr->window |= (PW_PLAYER);
1327         p_ptr->window |= (PW_SPELL);
1328 }