OSDN Git Service

49726a3d3025fe4888bfe2c80d5e688ae0f11e23
[hengbandforosx/hengbandosx.git] / src / cmd-action / cmd-spell.cpp
1 /*!
2  * @brief 魔法のインターフェイスと発動 / Purpose: Do everything for each spell
3  * @date 2013/12/31
4  * @author
5  * 2013 Deskull rearranged comment for Doxygen.
6  */
7
8 #include "cmd-action/cmd-spell.h"
9 #include "action/action-limited.h"
10 #include "autopick/autopick-reader-writer.h"
11 #include "avatar/avatar.h"
12 #include "cmd-action/cmd-mind.h"
13 #include "cmd-io/cmd-dump.h"
14 #include "core/asking-player.h"
15 #include "core/player-redraw-types.h"
16 #include "core/stuff-handler.h"
17 #include "core/window-redrawer.h"
18 #include "floor/floor-object.h"
19 #include "game-option/disturbance-options.h"
20 #include "game-option/input-options.h"
21 #include "game-option/text-display-options.h"
22 #include "grid/grid.h"
23 #include "inventory/inventory-slot-types.h"
24 #include "io/command-repeater.h"
25 #include "io/input-key-acceptor.h"
26 #include "io/input-key-requester.h"
27 #include "io/write-diary.h"
28 #include "locale/japanese.h"
29 #include "main/sound-definitions-table.h"
30 #include "main/sound-of-music.h"
31 #include "object-hook/hook-magic.h"
32 #include "object/item-tester-hooker.h"
33 #include "object/item-use-flags.h"
34 #include "object/object-info.h"
35 #include "player-base/player-class.h"
36 #include "player-info/class-info.h"
37 #include "player-info/samurai-data-type.h"
38 #include "player-info/self-info.h"
39 #include "player-status/player-energy.h"
40 #include "player/attack-defense-types.h"
41 #include "player/eldritch-horror.h"
42 #include "player/player-damage.h"
43 #include "player/player-realm.h"
44 #include "player/player-skill.h"
45 #include "player/player-status.h"
46 #include "player/special-defense-types.h"
47 #include "realm/realm-names-table.h"
48 #include "spell-kind/spells-random.h"
49 #include "spell-kind/spells-sight.h"
50 #include "spell-realm/spells-hex.h"
51 #include "spell/range-calc.h"
52 #include "spell/spell-info.h"
53 #include "spell/spells-describer.h"
54 #include "spell/spells-execution.h"
55 #include "spell/spells-summon.h"
56 #include "status/action-setter.h"
57 #include "status/bad-status-setter.h"
58 #include "status/base-status.h"
59 #include "status/experience.h"
60 #include "system/baseitem-info.h"
61 #include "system/floor-type-definition.h"
62 #include "system/item-entity.h"
63 #include "system/player-type-definition.h"
64 #include "system/redrawing-flags-updater.h"
65 #include "term/screen-processor.h"
66 #include "term/z-form.h"
67 #include "timed-effect/player-blindness.h"
68 #include "timed-effect/timed-effects.h"
69 #include "util/bit-flags-calculator.h"
70 #include "util/int-char-converter.h"
71 #include "view/display-messages.h"
72 #include "view/display-util.h"
73
74 static const int extra_magic_gain_exp = 4;
75
76 concptr KWD_DAM = _("損傷:", "dam ");
77 concptr KWD_RANGE = _("射程:", "rng ");
78 concptr KWD_DURATION = _("期間:", "dur ");
79 concptr KWD_SPHERE = _("範囲:", "range ");
80 concptr KWD_HEAL = _("回復:", "heal ");
81 concptr KWD_MANA = _("MP回復:", "heal SP ");
82 concptr KWD_POWER _("効力:", "power ");
83 concptr KWD_RANDOM = _("ランダム", "random");
84
85 /*!
86  * 魔法領域フラグ管理テーブル /
87  * Zangband uses this array instead of the spell flags table, as there
88  * are 5 realms of magic, each with 4 spellbooks and 8 spells per book -- TY
89  */
90 const uint32_t fake_spell_flags[4] = { 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
91
92 /*!
93  * @brief
94  * 魔法の効果を「キャプション:ダイス+定数値」のフォーマットで出力する / Generate dice info string such as "foo 2d10"
95  * @param str キャプション
96  * @param dice ダイス数
97  * @param sides ダイス目
98  * @param base 固定値
99  * @return フォーマットに従い整形された文字列
100  */
101 std::string info_string_dice(concptr str, DICE_NUMBER dice, DICE_SID sides, int base)
102 {
103     /* Fix value */
104     if (!dice) {
105         return format("%s%d", str, base);
106     }
107
108     /* Dice only */
109     else if (!base) {
110         return format("%s%dd%d", str, dice, sides);
111     }
112
113     /* Dice plus base value */
114     else {
115         return format("%s%dd%d%+d", str, dice, sides, base);
116     }
117 }
118
119 /*!
120  * @brief 魔法によるダメージを出力する / Generate damage-dice info string such as "dam 2d10"
121  * @param dice ダイス数
122  * @param sides ダイス目
123  * @param base 固定値
124  * @return フォーマットに従い整形された文字列
125  */
126 std::string info_damage(DICE_NUMBER dice, DICE_SID sides, int base)
127 {
128     return info_string_dice(_("損傷:", "dam "), dice, sides, base);
129 }
130
131 /*!
132  * @brief 魔法の効果時間を出力する / Generate duration info string such as "dur 20+1d20"
133  * @param base 固定値
134  * @param sides ダイス目
135  * @return フォーマットに従い整形された文字列
136  */
137 std::string info_duration(int base, DICE_SID sides)
138 {
139     return format(_("期間:%d+1d%d", "dur %d+1d%d"), base, sides);
140 }
141
142 /*!
143  * @brief 魔法の効果範囲を出力する / Generate range info string such as "range 5"
144  * @param range 効果範囲
145  * @return フォーマットに従い整形された文字列
146  */
147 std::string info_range(POSITION range)
148 {
149     return format(_("範囲:%d", "range %d"), range);
150 }
151
152 /*!
153  * @brief 魔法による回復量を出力する / Generate heal info string such as "heal 2d8"
154  * @param dice ダイス数
155  * @param sides ダイス目
156  * @param base 固定値
157  * @return フォーマットに従い整形された文字列
158  */
159 std::string info_heal(DICE_NUMBER dice, DICE_SID sides, int base)
160 {
161     return info_string_dice(_("回復:", "heal "), dice, sides, base);
162 }
163
164 /*!
165  * @brief 魔法効果発動までの遅延ターンを出力する / Generate delay info string such as "delay 15+1d15"
166  * @param base 固定値
167  * @param sides ダイス目
168  * @return フォーマットに従い整形された文字列
169  */
170 std::string info_delay(int base, DICE_SID sides)
171 {
172     return format(_("遅延:%d+1d%d", "delay %d+1d%d"), base, sides);
173 }
174
175 /*!
176  * @brief 魔法によるダメージを出力する(固定値&複数回処理) / Generate multiple-damage info string such as "dam 25 each"
177  * @param dam 固定値
178  * @return フォーマットに従い整形された文字列
179  */
180 std::string info_multi_damage(int dam)
181 {
182     return format(_("損傷:各%d", "dam %d each"), dam);
183 }
184
185 /*!
186  * @brief 魔法によるダメージを出力する(ダイスのみ&複数回処理) / Generate multiple-damage-dice info string such as "dam 5d2 each"
187  * @param dice ダイス数
188  * @param sides ダイス目
189  * @return フォーマットに従い整形された文字列
190  */
191 std::string info_multi_damage_dice(DICE_NUMBER dice, DICE_SID sides)
192 {
193     return format(_("損傷:各%dd%d", "dam %dd%d each"), dice, sides);
194 }
195
196 /*!
197  * @brief 魔法による一般的な効力値を出力する(固定値) / Generate power info string such as "power 100"
198  * @param power 固定値
199  * @return フォーマットに従い整形された文字列
200  */
201 std::string info_power(int power)
202 {
203     return format(_("効力:%d", "power %d"), power);
204 }
205
206 /*!
207  * @brief 魔法による一般的な効力値を出力する(ダイス値) / Generate power info string such as "power 100"
208  * @param dice ダイス数
209  * @param sides ダイス目
210  * @return フォーマットに従い整形された文字列
211  */
212 /*
213  * Generate power info string such as "power 1d100"
214  */
215 std::string info_power_dice(DICE_NUMBER dice, DICE_SID sides)
216 {
217     return format(_("効力:%dd%d", "power %dd%d"), dice, sides);
218 }
219
220 /*!
221  * @brief 魔法の効果半径を出力する / Generate radius info string such as "rad 100"
222  * @param rad 効果半径
223  * @return フォーマットに従い整形された文字列
224  */
225 std::string info_radius(POSITION rad)
226 {
227     return format(_("半径:%d", "rad %d"), rad);
228 }
229
230 /*!
231  * @brief 魔法効果の限界重量を出力する / Generate weight info string such as "max wgt 15"
232  * @param weight 最大重量
233  * @return フォーマットに従い整形された文字列
234  */
235 std::string info_weight(WEIGHT weight)
236 {
237 #ifdef JP
238     return format("最大重量:%d.%dkg", lb_to_kg_integer(weight), lb_to_kg_fraction(weight));
239 #else
240     return format("max wgt %d", weight / 10);
241 #endif
242 }
243
244 /*!
245  * @brief 魔法が利用可能かどうかを返す /
246  * Determine if a spell is "okay" for the player to cast or study
247  * The spell must be legible, not forgotten, and also, to cast,
248  * it must be known, and to study, it must not be known.
249  * @param spell 呪文ID
250  * @param learned 使用可能な判定ならばTRUE、学習可能かどうかの判定ならばFALSE
251  * @param study_pray 祈りの学習判定目的ならばTRUE
252  * @param use_realm 魔法領域ID
253  * @return 失敗率(%)
254  */
255 static bool spell_okay(PlayerType *player_ptr, int spell, bool learned, bool study_pray, int use_realm)
256 {
257     const magic_type *s_ptr;
258
259     /* Access the spell */
260     if (!is_magic(use_realm)) {
261         s_ptr = &technic_info[use_realm - MIN_TECHNIC][spell];
262     } else {
263         s_ptr = &mp_ptr->info[use_realm - 1][spell];
264     }
265
266     /* Spell is illegal */
267     if (s_ptr->slevel > player_ptr->lev) {
268         return false;
269     }
270
271     /* Spell is forgotten */
272     if ((use_realm == player_ptr->realm2) ? (player_ptr->spell_forgotten2 & (1UL << spell)) : (player_ptr->spell_forgotten1 & (1UL << spell))) {
273         /* Never okay */
274         return false;
275     }
276
277     if (PlayerClass(player_ptr).is_every_magic()) {
278         return true;
279     }
280
281     /* Spell is learned */
282     if ((use_realm == player_ptr->realm2) ? (player_ptr->spell_learned2 & (1UL << spell)) : (player_ptr->spell_learned1 & (1UL << spell))) {
283         /* Always true */
284         return !study_pray;
285     }
286
287     /* Okay to study, not to cast */
288     return !learned;
289 }
290
291 /*!
292  * @brief 領域魔法の閲覧、学習、使用選択するインターフェイス処理
293  * Allow user to choose a spell/prayer from the given book.
294  * @param sn 選択した魔法IDを返す参照ポインタ
295  * @param prompt 魔法を利用する際の動詞表記
296  * @param sval 魔道書のsval
297  * @param learned 閲覧/使用選択ならばTRUE、学習処理ならFALSE
298  * @param use_realm 魔法領域ID
299  * @return
300  * <pre>
301  * If a valid spell is chosen, saves it in '*sn' and returns TRUE
302  * If the user hits escape, returns FALSE, and set '*sn' to -1
303  * If there are no legal choices, returns FALSE, and sets '*sn' to -2
304  * The "prompt" should be "cast", "recite", or "study"
305  * The "known" should be TRUE for cast/pray, FALSE for study
306  * </pre>
307  */
308 static int get_spell(PlayerType *player_ptr, SPELL_IDX *sn, concptr prompt, int sval, bool learned, int16_t use_realm)
309 {
310     int i;
311     SPELL_IDX spell = -1;
312     int num = 0;
313     SPELL_IDX spells[64];
314     bool flag, redraw, okay;
315     char choice;
316     char out_val[160];
317     concptr p;
318     COMMAND_CODE code;
319     int menu_line = (use_menu ? 1 : 0);
320
321     /* Get the spell, if available */
322     if (repeat_pull(&code)) {
323         *sn = (SPELL_IDX)code;
324         /* Verify the spell */
325         if (spell_okay(player_ptr, *sn, learned, false, use_realm)) {
326             /* Success */
327             return true;
328         }
329     }
330
331     p = spell_category_name(mp_ptr->spell_book);
332
333     /* Extract spells */
334     for (spell = 0; spell < 32; spell++) {
335         /* Check for this spell */
336         if ((fake_spell_flags[sval] & (1UL << spell))) {
337             /* Collect this spell */
338             spells[num++] = spell;
339         }
340     }
341
342     /* Assume no usable spells */
343     okay = false;
344
345     /* Assume no spells available */
346     (*sn) = -2;
347
348     /* Check for "okay" spells */
349     for (i = 0; i < num; i++) {
350         /* Look for "okay" spells */
351         if (spell_okay(player_ptr, spells[i], learned, false, use_realm)) {
352             okay = true;
353         }
354     }
355
356     /* No "okay" spells */
357     if (!okay) {
358         return false;
359     }
360
361     PlayerClass pc(player_ptr);
362     auto is_every_magic = pc.is_every_magic();
363     if (((use_realm) != player_ptr->realm1) && ((use_realm) != player_ptr->realm2) && !is_every_magic) {
364         return false;
365     }
366     if (is_every_magic && !is_magic(use_realm)) {
367         return false;
368     }
369     if (pc.equals(PlayerClassType::RED_MAGE) && ((use_realm) != REALM_ARCANE) && (sval > 1)) {
370         return false;
371     }
372
373     /* Assume cancelled */
374     *sn = (-1);
375
376     flag = false;
377     redraw = false;
378
379     player_ptr->window_flags |= (PW_SPELL);
380     handle_stuff(player_ptr);
381
382     /* Build a prompt (accept all spells) */
383 #ifdef JP
384     const auto verb = conjugate_jverb(prompt, JVerbConjugationType::AND);
385     (void)strnfmt(out_val, 78, "(%s^:%c-%c, '*'で一覧, ESCで中断) どの%sを%s^ますか? ", p, I2A(0), I2A(num - 1), p, verb.data());
386 #else
387     (void)strnfmt(out_val, 78, "(%s^s %c-%c, *=List, ESC=exit) %s^ which %s? ", p, I2A(0), I2A(num - 1), prompt, p);
388 #endif
389
390     choice = (always_show_list || use_menu) ? ESCAPE : 1;
391     while (!flag) {
392         if (choice == ESCAPE) {
393             choice = ' ';
394         } else if (!get_com(out_val, &choice, true)) {
395             break;
396         }
397
398         auto should_redraw_cursor = true;
399         if (use_menu && choice != ' ') {
400             switch (choice) {
401             case '0': {
402                 screen_load();
403                 return false;
404             }
405
406             case '8':
407             case 'k':
408             case 'K': {
409                 menu_line += (num - 1);
410                 break;
411             }
412
413             case '2':
414             case 'j':
415             case 'J': {
416                 menu_line++;
417                 break;
418             }
419
420             case 'x':
421             case 'X':
422             case '\r':
423             case '\n': {
424                 i = menu_line - 1;
425                 should_redraw_cursor = false;
426                 break;
427             }
428             }
429             if (menu_line > num) {
430                 menu_line -= num;
431             }
432             /* Display a list of spells */
433             print_spells(player_ptr, menu_line, spells, num, 1, 15, use_realm);
434             if (should_redraw_cursor) {
435                 continue;
436             }
437         } else {
438             /* Request redraw */
439             if ((choice == ' ') || (choice == '*') || (choice == '?')) {
440                 /* Show the list */
441                 if (!redraw) {
442                     redraw = true;
443                     screen_save();
444
445                     /* Display a list of spells */
446                     print_spells(player_ptr, menu_line, spells, num, 1, 15, use_realm);
447                 }
448
449                 /* Hide the list */
450                 else {
451                     if (use_menu) {
452                         continue;
453                     }
454
455                     /* Hide list */
456                     redraw = false;
457                     screen_load();
458                 }
459
460                 /* Redo asking */
461                 continue;
462             }
463
464             i = A2I(choice);
465         }
466
467         /* Totally Illegal */
468         if ((i < 0) || (i >= num)) {
469             bell();
470             continue;
471         }
472
473         /* Save the spell index */
474         spell = spells[i];
475
476         /* Require "okay" spells */
477         if (!spell_okay(player_ptr, spell, learned, false, use_realm)) {
478             bell();
479 #ifdef JP
480             msg_format("その%sを%sことはできません。", p, prompt);
481 #else
482             msg_format("You may not %s that %s.", prompt, p);
483 #endif
484
485             continue;
486         }
487
488         /* Stop the loop */
489         flag = true;
490     }
491
492     if (redraw) {
493         screen_load();
494     }
495
496     player_ptr->window_flags |= (PW_SPELL);
497     handle_stuff(player_ptr);
498
499     /* Abort if needed */
500     if (!flag) {
501         return false;
502     }
503
504     /* Save the choice */
505     (*sn) = spell;
506
507     repeat_push((COMMAND_CODE)spell);
508
509     /* Success */
510     return true;
511 }
512
513 /*!
514  * @brief プレイヤーの職業が練気術師の時、領域魔法と練気術を切り換える処理のインターフェイス
515  * @param browse_only 魔法と技能の閲覧を行うならばTRUE
516  * @return 魔道書を一冊も持っていないならTRUEを返す
517  */
518 static void confirm_use_force(PlayerType *player_ptr, bool browse_only)
519 {
520     char which;
521     COMMAND_CODE code;
522
523     /* Get the item index */
524     if (repeat_pull(&code) && (code == INVEN_FORCE)) {
525         browse_only ? do_cmd_mind_browse(player_ptr) : do_cmd_mind(player_ptr);
526         return;
527     }
528
529     /* Show the prompt */
530     prt(_("('w'練気術, ESC) 'w'かESCを押してください。 ", "(w for the Force, ESC) Hit 'w' or ESC. "), 0, 0);
531
532     while (true) {
533         /* Get a key */
534         which = inkey();
535
536         if (which == ESCAPE) {
537             break;
538         } else if (which == 'w') {
539             repeat_push(INVEN_FORCE);
540             break;
541         }
542     }
543
544     /* Clear the prompt line */
545     prt("", 0, 0);
546
547     if (which == 'w') {
548         browse_only ? do_cmd_mind_browse(player_ptr) : do_cmd_mind(player_ptr);
549     }
550 }
551
552 static FuncItemTester get_castable_spellbook_tester(PlayerType *player_ptr)
553 {
554     return FuncItemTester([](auto p_ptr, auto o_ptr) { return check_book_realm(p_ptr, o_ptr->bi_key); }, player_ptr);
555 }
556
557 static FuncItemTester get_learnable_spellbook_tester(PlayerType *player_ptr)
558 {
559     if (player_ptr->realm2 == REALM_NONE) {
560         return get_castable_spellbook_tester(player_ptr);
561     } else {
562         return FuncItemTester(item_tester_learn_spell, player_ptr);
563     }
564 }
565
566 /*!
567  * @brief プレイヤーの魔法と技能を閲覧するコマンドのメインルーチン /
568  * Peruse the spells/prayers in a book
569  * @details
570  * <pre>
571  * Note that *all* spells in the book are listed
572  *
573  * Note that browsing is allowed while confused or blind,
574  * and in the dark, primarily to allow browsing in stores.
575  * </pre>
576  */
577 void do_cmd_browse(PlayerType *player_ptr)
578 {
579     OBJECT_IDX item;
580     SPELL_IDX spell = -1;
581     int num = 0;
582
583     SPELL_IDX spells[64];
584
585     /* Warriors are illiterate */
586     PlayerClass pc(player_ptr);
587     if (!(player_ptr->realm1 || player_ptr->realm2) && !pc.is_every_magic()) {
588         msg_print(_("本を読むことができない!", "You cannot read books!"));
589         return;
590     }
591
592     pc.break_samurai_stance({ SamuraiStanceType::MUSOU });
593
594     if (pc.equals(PlayerClassType::FORCETRAINER)) {
595         if (player_has_no_spellbooks(player_ptr)) {
596             confirm_use_force(player_ptr, true);
597             return;
598         }
599     }
600
601     /* Restrict choices to "useful" books */
602     auto item_tester = get_learnable_spellbook_tester(player_ptr);
603
604     constexpr auto q = _("どの本を読みますか? ", "Browse which book? ");
605     constexpr auto s = _("読める本がない。", "You have no books that you can read.");
606     constexpr auto options = USE_INVEN | USE_FLOOR;
607     const auto *o_ptr = choose_object(player_ptr, &item, q, s, options | (pc.equals(PlayerClassType::FORCETRAINER) ? USE_FORCE : 0), item_tester);
608     if (o_ptr == nullptr) {
609         if (item == INVEN_FORCE) /* the_force */
610         {
611             do_cmd_mind_browse(player_ptr);
612             return;
613         }
614         return;
615     }
616
617     /* Access the item's sval */
618     const auto tval = o_ptr->bi_key.tval();
619     const auto sval = o_ptr->bi_key.sval().value();
620     short use_realm = tval2realm(tval);
621
622     /* Track the object kind */
623     object_kind_track(player_ptr, o_ptr->bi_id);
624     handle_stuff(player_ptr);
625
626     /* Extract spells */
627     for (spell = 0; spell < 32; spell++) {
628         /* Check for this spell */
629         if ((fake_spell_flags[sval] & (1UL << spell))) {
630             /* Collect this spell */
631             spells[num++] = spell;
632         }
633     }
634
635     screen_save();
636     prt("", 0, 0);
637
638     /* Keep browsing spells.  Exit browsing on cancel. */
639     while (true) {
640         /* Ask for a spell, allow cancel */
641         if (!get_spell(player_ptr, &spell, _("読む", "browse"), sval, true, use_realm)) {
642             /* If cancelled, leave immediately. */
643             if (spell == -1) {
644                 break;
645             }
646
647             /* Display a list of spells */
648             print_spells(player_ptr, 0, spells, num, 1, 15, use_realm);
649
650             /* Notify that there's nothing to see, and wait. */
651             if (use_realm == REALM_HISSATSU) {
652                 prt(_("読める技がない。", "No techniques to browse."), 0, 0);
653             } else {
654                 prt(_("読める呪文がない。", "No spells to browse."), 0, 0);
655             }
656             (void)inkey();
657
658             screen_load();
659
660             return;
661         }
662
663         /* Clear lines, position cursor  (really should use strlen here) */
664         term_erase(14, 14, 255);
665         term_erase(14, 13, 255);
666         term_erase(14, 12, 255);
667         term_erase(14, 11, 255);
668
669         const auto spell_desc = exe_spell(player_ptr, use_realm, spell, SpellProcessType::DESCRIPTION);
670         display_wrap_around(spell_desc.value(), 62, 11, 15);
671     }
672     screen_load();
673 }
674
675 /*!
676  * @brief プレイヤーの第二魔法領域を変更する /
677  * @param player_ptr プレイヤーへの参照ポインタ
678  * @param next_realm 変更先の魔法領域ID
679  */
680 static void change_realm2(PlayerType *player_ptr, int16_t next_realm)
681 {
682     int i, j = 0;
683     char tmp[80];
684
685     for (i = 0; i < 64; i++) {
686         player_ptr->spell_order[j] = player_ptr->spell_order[i];
687         if (player_ptr->spell_order[i] < 32) {
688             j++;
689         }
690     }
691     for (; j < 64; j++) {
692         player_ptr->spell_order[j] = 99;
693     }
694
695     for (i = 32; i < 64; i++) {
696         player_ptr->spell_exp[i] = PlayerSkill::spell_exp_at(PlayerSkillRank::UNSKILLED);
697     }
698     player_ptr->spell_learned2 = 0L;
699     player_ptr->spell_worked2 = 0L;
700     player_ptr->spell_forgotten2 = 0L;
701
702     constexpr auto mes = _("魔法の領域を%sから%sに変更した。", "changed magic realm from %s to %s.");
703     strnfmt(tmp, sizeof(tmp), mes, realm_names[player_ptr->realm2], realm_names[next_realm]);
704     exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, tmp);
705     player_ptr->old_realm |= 1U << (player_ptr->realm2 - 1);
706     player_ptr->realm2 = next_realm;
707
708     const auto flags = {
709         StatusRedrawingFlag::REORDER,
710         StatusRedrawingFlag::SPELLS,
711     };
712     RedrawingFlagsUpdater::get_instance().set_flags(flags);
713     handle_stuff(player_ptr);
714
715     /* Load an autopick preference file */
716     autopick_load_pref(player_ptr, false);
717 }
718
719 /*!
720  * @brief 魔法を学習するコマンドのメインルーチン /
721  * Study a book to gain a new spell/prayer
722  */
723 void do_cmd_study(PlayerType *player_ptr)
724 {
725     auto increment = 0;
726     auto learned = false;
727
728     /* Spells of realm2 will have an increment of +32 */
729     SPELL_IDX spell = -1;
730     const auto p = spell_category_name(mp_ptr->spell_book);
731     if (!player_ptr->realm1) {
732         msg_print(_("本を読むことができない!", "You cannot read books!"));
733         return;
734     }
735
736     if (cmd_limit_blind(player_ptr) || cmd_limit_confused(player_ptr)) {
737         return;
738     }
739
740     if (player_ptr->new_spells == 0) {
741         msg_format(_("新しい%sを覚えることはできない!", "You cannot learn any new %ss!"), p);
742         return;
743     }
744
745     PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::MUSOU });
746
747 #ifdef JP
748     if (player_ptr->new_spells < 10) {
749         msg_format("あと %d つの%sを学べる。", player_ptr->new_spells, p);
750     } else {
751         msg_format("あと %d 個の%sを学べる。", player_ptr->new_spells, p);
752     }
753 #else
754     msg_format("You can learn %d new %s%s.", player_ptr->new_spells, p, (player_ptr->new_spells == 1 ? "" : "s"));
755 #endif
756
757     msg_print(nullptr);
758
759     /* Restrict choices to "useful" books */
760     auto item_tester = get_learnable_spellbook_tester(player_ptr);
761
762     const auto q = _("どの本から学びますか? ", "Study which book? ");
763     const auto s = _("読める本がない。", "You have no books that you can read.");
764
765     short item;
766     const auto *o_ptr = choose_object(player_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), item_tester);
767     if (o_ptr == nullptr) {
768         return;
769     }
770
771     const auto tval = o_ptr->bi_key.tval();
772     const auto sval = o_ptr->bi_key.sval().value();
773     if (tval == get_realm2_book(player_ptr)) {
774         increment = 32;
775     } else if (tval != get_realm1_book(player_ptr)) {
776         if (!get_check(_("本当に魔法の領域を変更しますか?", "Really, change magic realm? "))) {
777             return;
778         }
779
780         change_realm2(player_ptr, tval2realm(tval));
781         increment = 32;
782     }
783
784     /* Track the object kind */
785     object_kind_track(player_ptr, o_ptr->bi_id);
786     handle_stuff(player_ptr);
787
788     /* Mage -- Learn a selected spell */
789     if (mp_ptr->spell_book != ItemKindType::LIFE_BOOK) {
790         /* Ask for a spell, allow cancel */
791         if (!get_spell(player_ptr, &spell, _("学ぶ", "study"), sval, false, tval2realm(tval)) && (spell == -1)) {
792             return;
793         }
794     }
795
796     /* Priest -- Learn a random prayer */
797     else {
798         int k = 0;
799         int gift = -1;
800
801         /* Extract spells */
802         for (spell = 0; spell < 32; spell++) {
803             /* Check spells in the book */
804             if ((fake_spell_flags[sval] & (1UL << spell))) {
805                 /* Skip non "okay" prayers */
806                 if (!spell_okay(player_ptr, spell, false, true, (increment ? player_ptr->realm2 : player_ptr->realm1))) {
807                     continue;
808                 }
809
810                 /* Hack -- Prepare the randomizer */
811                 k++;
812
813                 /* Hack -- Apply the randomizer */
814                 if (one_in_(k)) {
815                     gift = spell;
816                 }
817             }
818         }
819
820         /* Accept gift */
821         spell = gift;
822     }
823
824     /* Nothing to study */
825     if (spell < 0) {
826         msg_format(_("その本には学ぶべき%sがない。", "You cannot learn any %ss in that book."), p);
827
828         /* Abort */
829         return;
830     }
831
832     if (increment) {
833         spell += increment;
834     }
835
836     /* Learn the spell */
837     if (spell < 32) {
838         if (player_ptr->spell_learned1 & (1UL << spell)) {
839             learned = true;
840         } else {
841             player_ptr->spell_learned1 |= (1UL << spell);
842         }
843     } else {
844         if (player_ptr->spell_learned2 & (1UL << (spell - 32))) {
845             learned = true;
846         } else {
847             player_ptr->spell_learned2 |= (1UL << (spell - 32));
848         }
849     }
850
851     if (learned) {
852         auto max_exp = PlayerSkill::spell_exp_at((spell < 32) ? PlayerSkillRank::MASTER : PlayerSkillRank::EXPERT);
853         const auto old_exp = player_ptr->spell_exp[spell];
854         const auto realm = increment ? player_ptr->realm2 : player_ptr->realm1;
855         const auto spell_name = exe_spell(player_ptr, realm, spell % 32, SpellProcessType::NAME);
856
857         if (old_exp >= max_exp) {
858             msg_format(_("その%sは完全に使いこなせるので学ぶ必要はない。", "You don't need to study this %s anymore."), p);
859             return;
860         }
861 #ifdef JP
862         if (!get_check(format("%sの%sをさらに学びます。よろしいですか?", spell_name->data(), p)))
863 #else
864         if (!get_check(format("You will study a %s of %s again. Are you sure? ", p, spell_name->data())))
865 #endif
866         {
867             return;
868         }
869
870         auto new_rank = PlayerSkill(player_ptr).gain_spell_skill_exp_over_learning(spell);
871         auto new_rank_str = PlayerSkill::skill_rank_str(new_rank);
872         msg_format(_("%sの熟練度が%sに上がった。", "Your proficiency of %s is now %s rank."), spell_name->data(), new_rank_str);
873     } else {
874         /* Find the next open entry in "player_ptr->spell_order[]" */
875         int i;
876         for (i = 0; i < 64; i++) {
877             /* Stop at the first empty space */
878             if (player_ptr->spell_order[i] == 99) {
879                 break;
880             }
881         }
882
883         /* Add the spell to the known list */
884         player_ptr->spell_order[i++] = spell;
885
886         /* Mention the result */
887         const auto realm = increment ? player_ptr->realm2 : player_ptr->realm1;
888         const auto spell_name = exe_spell(player_ptr, realm, spell % 32, SpellProcessType::NAME);
889 #ifdef JP
890         if (mp_ptr->spell_book == ItemKindType::MUSIC_BOOK) {
891             msg_format("%sを学んだ。", spell_name->data());
892         } else {
893             msg_format("%sの%sを学んだ。", spell_name->data(), p);
894         }
895 #else
896         msg_format("You have learned the %s of %s.", p, spell_name->data());
897 #endif
898     }
899
900     PlayerEnergy(player_ptr).set_player_turn_energy(100);
901
902     switch (mp_ptr->spell_book) {
903     case ItemKindType::LIFE_BOOK:
904         chg_virtue(player_ptr, Virtue::FAITH, 1);
905         break;
906     case ItemKindType::DEATH_BOOK:
907         chg_virtue(player_ptr, Virtue::UNLIFE, 1);
908         break;
909     case ItemKindType::NATURE_BOOK:
910         chg_virtue(player_ptr, Virtue::NATURE, 1);
911         break;
912     default:
913         chg_virtue(player_ptr, Virtue::KNOWLEDGE, 1);
914         break;
915     }
916
917     sound(SOUND_STUDY);
918
919     /* One less spell available */
920     player_ptr->learned_spells++;
921
922     auto &rfu = RedrawingFlagsUpdater::get_instance();
923     rfu.set_flag(StatusRedrawingFlag::SPELLS);
924     update_creature(player_ptr);
925
926     /* Redraw object recall */
927     player_ptr->window_flags |= (PW_ITEM_KNOWLEDGTE);
928 }
929
930 /*!
931  * @brief 魔法を詠唱するコマンドのメインルーチン /
932  * Cast a spell
933  * @param player_ptr プレイヤーへの参照ポインタ
934  * @return 詠唱したらtrue
935  */
936 bool do_cmd_cast(PlayerType *player_ptr)
937 {
938     SPELL_IDX spell;
939     int16_t realm;
940     int chance;
941     auto increment = 0;
942     int16_t use_realm;
943     MANA_POINT need_mana;
944
945     const magic_type *s_ptr;
946     auto over_exerted = false;
947
948     /* Require spell ability */
949     PlayerClass pc(player_ptr);
950     auto is_every_magic = pc.is_every_magic();
951     if (!player_ptr->realm1 && !is_every_magic) {
952         msg_print(_("呪文を唱えられない!", "You cannot cast spells!"));
953         return false;
954     }
955
956     if (player_ptr->effects()->blindness()->is_blind() || no_lite(player_ptr)) {
957         if (pc.equals(PlayerClassType::FORCETRAINER)) {
958             confirm_use_force(player_ptr, false);
959         } else {
960             msg_print(_("目が見えない!", "You cannot see!"));
961             flush();
962         }
963
964         return false;
965     }
966
967     if (cmd_limit_confused(player_ptr)) {
968         return false;
969     }
970
971     if (player_ptr->realm1 == REALM_HEX) {
972         if (SpellHex(player_ptr).is_casting_full_capacity()) {
973             auto flag = false;
974             msg_print(_("これ以上新しい呪文を詠唱することはできない。", "Can not cast more spells."));
975             flush();
976             if (player_ptr->lev >= 35) {
977                 flag = SpellHex(player_ptr).stop_spells_with_selection();
978             }
979
980             if (!flag) {
981                 return false;
982             }
983         }
984     }
985
986     if (pc.equals(PlayerClassType::FORCETRAINER)) {
987         if (player_has_no_spellbooks(player_ptr)) {
988             confirm_use_force(player_ptr, false);
989             return true; //!< 錬気キャンセル時の処理がない
990         }
991     }
992
993     const auto prayer = spell_category_name(mp_ptr->spell_book);
994     const auto q = _("どの呪文書を使いますか? ", "Use which book? ");
995     const auto s = _("呪文書がない!", "You have no spell books!");
996     auto item_tester = get_castable_spellbook_tester(player_ptr);
997     const auto options = USE_INVEN | USE_FLOOR | (pc.equals(PlayerClassType::FORCETRAINER) ? USE_FORCE : 0);
998     short item;
999     const auto *o_ptr = choose_object(player_ptr, &item, q, s, options, item_tester);
1000     if (o_ptr == nullptr) {
1001         if (item == INVEN_FORCE) {
1002             do_cmd_mind(player_ptr);
1003             return true; //!< 錬気キャンセル時の処理がない
1004         }
1005
1006         return false;
1007     }
1008
1009     const auto tval = o_ptr->bi_key.tval();
1010     const auto sval = o_ptr->bi_key.sval().value();
1011     if (!is_every_magic && (tval == get_realm2_book(player_ptr))) {
1012         increment = 32;
1013     }
1014
1015     /* Track the object kind */
1016     object_kind_track(player_ptr, o_ptr->bi_id);
1017     handle_stuff(player_ptr);
1018
1019     if (is_every_magic) {
1020         realm = tval2realm(tval);
1021     } else if (increment) {
1022         realm = player_ptr->realm2;
1023     } else {
1024         realm = player_ptr->realm1;
1025     }
1026
1027     /* Ask for a spell */
1028 #ifdef JP
1029     if (!get_spell(player_ptr, &spell,
1030             ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK)       ? "詠唱する"
1031                 : (mp_ptr->spell_book == ItemKindType::MUSIC_BOOK) ? "歌う"
1032                                                                    : "唱える"),
1033             sval, true, realm)) {
1034         if (spell == -2) {
1035             msg_format("その本には知っている%sがない。", prayer);
1036         }
1037         return false;
1038     }
1039 #else
1040     if (!get_spell(player_ptr, &spell, ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK) ? "recite" : "cast"), sval, true, realm)) {
1041         if (spell == -2) {
1042             msg_format("You don't know any %ss in that book.", prayer);
1043         }
1044         return false;
1045     }
1046 #endif
1047
1048     use_realm = tval2realm(tval);
1049     if (use_realm == REALM_HEX) {
1050         if (SpellHex(player_ptr).is_spelling_specific(spell)) {
1051             msg_print(_("その呪文はすでに詠唱中だ。", "You are already casting it."));
1052             return false;
1053         }
1054     }
1055
1056     if (!is_magic(use_realm)) {
1057         s_ptr = &technic_info[use_realm - MIN_TECHNIC][spell];
1058     } else {
1059         s_ptr = &mp_ptr->info[realm - 1][spell];
1060     }
1061
1062     /* Extract mana consumption rate */
1063     need_mana = mod_need_mana(player_ptr, s_ptr->smana, spell, realm);
1064
1065     /* Verify "dangerous" spells */
1066     if (need_mana > player_ptr->csp) {
1067         if (flush_failure) {
1068             flush();
1069         }
1070
1071         /* Warning */
1072 #ifdef JP
1073         msg_format("その%sを%sのに十分なマジックポイントがない。", prayer,
1074             ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK)      ? "詠唱する"
1075                 : (mp_ptr->spell_book == ItemKindType::LIFE_BOOK) ? "歌う"
1076                                                                   : "唱える"));
1077 #else
1078         msg_format("You do not have enough mana to %s this %s.", ((mp_ptr->spell_book == ItemKindType::LIFE_BOOK) ? "recite" : "cast"), prayer);
1079 #endif
1080
1081         if (!over_exert) {
1082             return false;
1083         }
1084
1085         /* Verify */
1086         if (!get_check_strict(player_ptr, _("それでも挑戦しますか? ", "Attempt it anyway? "), CHECK_OKAY_CANCEL)) {
1087             return false;
1088         }
1089     }
1090
1091     /* Spell failure chance */
1092     chance = spell_chance(player_ptr, spell, use_realm);
1093
1094     /* Failed spell */
1095     if (randint0(100) < chance) {
1096         if (flush_failure) {
1097             flush();
1098         }
1099
1100         msg_format(_("%sをうまく唱えられなかった!", "You failed to get the %s off!"), prayer);
1101         sound(SOUND_FAIL);
1102
1103         switch (realm) {
1104         case REALM_LIFE:
1105             if (randint1(100) < chance) {
1106                 chg_virtue(player_ptr, Virtue::VITALITY, -1);
1107             }
1108             break;
1109         case REALM_DEATH:
1110             if (randint1(100) < chance) {
1111                 chg_virtue(player_ptr, Virtue::UNLIFE, -1);
1112             }
1113             break;
1114         case REALM_NATURE:
1115             if (randint1(100) < chance) {
1116                 chg_virtue(player_ptr, Virtue::NATURE, -1);
1117             }
1118             break;
1119         case REALM_DAEMON:
1120             if (randint1(100) < chance) {
1121                 chg_virtue(player_ptr, Virtue::JUSTICE, 1);
1122             }
1123             break;
1124         case REALM_CRUSADE:
1125             if (randint1(100) < chance) {
1126                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1127             }
1128             break;
1129         case REALM_HEX:
1130             if (randint1(100) < chance) {
1131                 chg_virtue(player_ptr, Virtue::COMPASSION, -1);
1132             }
1133             break;
1134         default:
1135             if (randint1(100) < chance) {
1136                 chg_virtue(player_ptr, Virtue::KNOWLEDGE, -1);
1137             }
1138             break;
1139         }
1140
1141         /* Failure casting may activate some side effect */
1142         exe_spell(player_ptr, realm, spell, SpellProcessType::FAIL);
1143
1144         if ((tval == ItemKindType::CHAOS_BOOK) && (randint1(100) < spell)) {
1145             msg_print(_("カオス的な効果を発生した!", "You produce a chaotic effect!"));
1146             wild_magic(player_ptr, spell);
1147         } else if ((tval == ItemKindType::DEATH_BOOK) && (randint1(100) < spell)) {
1148             if ((sval == 3) && one_in_(2)) {
1149                 sanity_blast(player_ptr, 0, true);
1150             } else {
1151                 msg_print(_("痛い!", "It hurts!"));
1152                 take_hit(player_ptr, DAMAGE_LOSELIFE, damroll(sval + 1, 6), _("暗黒魔法の逆流", "a miscast Death spell"));
1153
1154                 if ((spell > 15) && one_in_(6) && !player_ptr->hold_exp) {
1155                     lose_exp(player_ptr, spell * 250);
1156                 }
1157             }
1158         } else if ((tval == ItemKindType::MUSIC_BOOK) && (randint1(200) < spell)) {
1159             msg_print(_("いやな音が響いた", "An infernal sound echoed."));
1160             aggravate_monsters(player_ptr, 0);
1161         }
1162         if (randint1(100) >= chance) {
1163             chg_virtue(player_ptr, Virtue::CHANCE, -1);
1164         }
1165     }
1166
1167     /* Process spell */
1168     else {
1169         /* Canceled spells cost neither a turn nor mana */
1170         if (!exe_spell(player_ptr, realm, spell, SpellProcessType::CAST)) {
1171             return false;
1172         }
1173
1174         if (randint1(100) < chance) {
1175             chg_virtue(player_ptr, Virtue::CHANCE, 1);
1176         }
1177
1178         /* A spell was cast */
1179         if (!(increment ? (player_ptr->spell_worked2 & (1UL << spell)) : (player_ptr->spell_worked1 & (1UL << spell))) && !is_every_magic) {
1180             int e = s_ptr->sexp;
1181
1182             /* The spell worked */
1183             if (realm == player_ptr->realm1) {
1184                 player_ptr->spell_worked1 |= (1UL << spell);
1185             } else {
1186                 player_ptr->spell_worked2 |= (1UL << spell);
1187             }
1188
1189             gain_exp(player_ptr, e * s_ptr->slevel);
1190             player_ptr->window_flags |= (PW_ITEM_KNOWLEDGTE);
1191
1192             switch (realm) {
1193             case REALM_LIFE:
1194                 chg_virtue(player_ptr, Virtue::TEMPERANCE, 1);
1195                 chg_virtue(player_ptr, Virtue::COMPASSION, 1);
1196                 chg_virtue(player_ptr, Virtue::VITALITY, 1);
1197                 chg_virtue(player_ptr, Virtue::DILIGENCE, 1);
1198                 break;
1199             case REALM_DEATH:
1200                 chg_virtue(player_ptr, Virtue::UNLIFE, 1);
1201                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1202                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1203                 chg_virtue(player_ptr, Virtue::VITALITY, -1);
1204                 break;
1205             case REALM_DAEMON:
1206                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1207                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1208                 chg_virtue(player_ptr, Virtue::HONOUR, -1);
1209                 chg_virtue(player_ptr, Virtue::TEMPERANCE, -1);
1210                 break;
1211             case REALM_CRUSADE:
1212                 chg_virtue(player_ptr, Virtue::FAITH, 1);
1213                 chg_virtue(player_ptr, Virtue::JUSTICE, 1);
1214                 chg_virtue(player_ptr, Virtue::SACRIFICE, 1);
1215                 chg_virtue(player_ptr, Virtue::HONOUR, 1);
1216                 break;
1217             case REALM_NATURE:
1218                 chg_virtue(player_ptr, Virtue::NATURE, 1);
1219                 chg_virtue(player_ptr, Virtue::HARMONY, 1);
1220                 break;
1221             case REALM_HEX:
1222                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1223                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1224                 chg_virtue(player_ptr, Virtue::HONOUR, -1);
1225                 chg_virtue(player_ptr, Virtue::COMPASSION, -1);
1226                 break;
1227             default:
1228                 chg_virtue(player_ptr, Virtue::KNOWLEDGE, 1);
1229                 break;
1230             }
1231         }
1232         switch (realm) {
1233         case REALM_LIFE:
1234             if (randint1(100 + player_ptr->lev) < need_mana) {
1235                 chg_virtue(player_ptr, Virtue::TEMPERANCE, 1);
1236             }
1237             if (randint1(100 + player_ptr->lev) < need_mana) {
1238                 chg_virtue(player_ptr, Virtue::COMPASSION, 1);
1239             }
1240             if (randint1(100 + player_ptr->lev) < need_mana) {
1241                 chg_virtue(player_ptr, Virtue::VITALITY, 1);
1242             }
1243             if (randint1(100 + player_ptr->lev) < need_mana) {
1244                 chg_virtue(player_ptr, Virtue::DILIGENCE, 1);
1245             }
1246             break;
1247         case REALM_DEATH:
1248             if (randint1(100 + player_ptr->lev) < need_mana) {
1249                 chg_virtue(player_ptr, Virtue::UNLIFE, 1);
1250             }
1251             if (randint1(100 + player_ptr->lev) < need_mana) {
1252                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1253             }
1254             if (randint1(100 + player_ptr->lev) < need_mana) {
1255                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1256             }
1257             if (randint1(100 + player_ptr->lev) < need_mana) {
1258                 chg_virtue(player_ptr, Virtue::VITALITY, -1);
1259             }
1260             break;
1261         case REALM_DAEMON:
1262             if (randint1(100 + player_ptr->lev) < need_mana) {
1263                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1264             }
1265             if (randint1(100 + player_ptr->lev) < need_mana) {
1266                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1267             }
1268             if (randint1(100 + player_ptr->lev) < need_mana) {
1269                 chg_virtue(player_ptr, Virtue::HONOUR, -1);
1270             }
1271             if (randint1(100 + player_ptr->lev) < need_mana) {
1272                 chg_virtue(player_ptr, Virtue::TEMPERANCE, -1);
1273             }
1274             break;
1275         case REALM_CRUSADE:
1276             if (randint1(100 + player_ptr->lev) < need_mana) {
1277                 chg_virtue(player_ptr, Virtue::FAITH, 1);
1278             }
1279             if (randint1(100 + player_ptr->lev) < need_mana) {
1280                 chg_virtue(player_ptr, Virtue::JUSTICE, 1);
1281             }
1282             if (randint1(100 + player_ptr->lev) < need_mana) {
1283                 chg_virtue(player_ptr, Virtue::SACRIFICE, 1);
1284             }
1285             if (randint1(100 + player_ptr->lev) < need_mana) {
1286                 chg_virtue(player_ptr, Virtue::HONOUR, 1);
1287             }
1288             break;
1289         case REALM_NATURE:
1290             if (randint1(100 + player_ptr->lev) < need_mana) {
1291                 chg_virtue(player_ptr, Virtue::NATURE, 1);
1292             }
1293             if (randint1(100 + player_ptr->lev) < need_mana) {
1294                 chg_virtue(player_ptr, Virtue::HARMONY, 1);
1295             }
1296             break;
1297         case REALM_HEX:
1298             if (randint1(100 + player_ptr->lev) < need_mana) {
1299                 chg_virtue(player_ptr, Virtue::JUSTICE, -1);
1300             }
1301             if (randint1(100 + player_ptr->lev) < need_mana) {
1302                 chg_virtue(player_ptr, Virtue::FAITH, -1);
1303             }
1304             if (randint1(100 + player_ptr->lev) < need_mana) {
1305                 chg_virtue(player_ptr, Virtue::HONOUR, -1);
1306             }
1307             if (randint1(100 + player_ptr->lev) < need_mana) {
1308                 chg_virtue(player_ptr, Virtue::COMPASSION, -1);
1309             }
1310             break;
1311         }
1312         if (any_bits(mp_ptr->spell_xtra, extra_magic_gain_exp)) {
1313             PlayerSkill(player_ptr).gain_spell_skill_exp(realm, spell);
1314         }
1315     }
1316
1317     PlayerEnergy(player_ptr).set_player_turn_energy(100);
1318
1319     /* Sufficient mana */
1320     if (need_mana <= player_ptr->csp) {
1321         /* Use some mana */
1322         player_ptr->csp -= need_mana;
1323     } else {
1324         over_exerted = true;
1325     }
1326
1327     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::MP);
1328
1329     /* Over-exert the player */
1330     if (over_exerted) {
1331         int oops = need_mana;
1332         player_ptr->csp = 0;
1333         player_ptr->csp_frac = 0;
1334         msg_print(_("精神を集中しすぎて気を失ってしまった!", "You faint from the effort!"));
1335         (void)BadStatusSetter(player_ptr).mod_paralysis(randint1(5 * oops + 1));
1336         switch (realm) {
1337         case REALM_LIFE:
1338             chg_virtue(player_ptr, Virtue::VITALITY, -10);
1339             break;
1340         case REALM_DEATH:
1341             chg_virtue(player_ptr, Virtue::UNLIFE, -10);
1342             break;
1343         case REALM_DAEMON:
1344             chg_virtue(player_ptr, Virtue::JUSTICE, 10);
1345             break;
1346         case REALM_NATURE:
1347             chg_virtue(player_ptr, Virtue::NATURE, -10);
1348             break;
1349         case REALM_CRUSADE:
1350             chg_virtue(player_ptr, Virtue::JUSTICE, -10);
1351             break;
1352         case REALM_HEX:
1353             chg_virtue(player_ptr, Virtue::COMPASSION, 10);
1354             break;
1355         default:
1356             chg_virtue(player_ptr, Virtue::KNOWLEDGE, -10);
1357             break;
1358         }
1359
1360         /* Damage CON (possibly permanently) */
1361         if (randint0(100) < 50) {
1362             bool perm = (randint0(100) < 25);
1363
1364             msg_print(_("体を悪くしてしまった!", "You have damaged your health!"));
1365
1366             /* Reduce constitution */
1367             (void)dec_stat(player_ptr, A_CON, 15 + randint1(10), perm);
1368         }
1369     }
1370
1371     player_ptr->window_flags |= (PW_PLAYER);
1372     player_ptr->window_flags |= (PW_SPELL);
1373
1374     return true; //!< @note 詠唱した
1375 }