OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / realm / realm-song.cpp
1 #include "cmd-action/cmd-spell.h"
2 #include "core/window-redrawer.h"
3 #include "effect/effect-characteristics.h"
4 #include "effect/effect-processor.h"
5 #include "hpmp/hp-mp-processor.h"
6 #include "player-info/class-info.h"
7 #include "player/attack-defense-types.h"
8 #include "player/player-status.h"
9 #include "realm/realm-song-numbers.h"
10 #include "spell-kind/earthquake.h"
11 #include "spell-kind/spells-detection.h"
12 #include "spell-kind/spells-floor.h"
13 #include "spell-kind/spells-grid.h"
14 #include "spell-kind/spells-launcher.h"
15 #include "spell-kind/spells-lite.h"
16 #include "spell-kind/spells-neighbor.h"
17 #include "spell-kind/spells-sight.h"
18 #include "spell-kind/spells-world.h"
19 #include "spell-realm/spells-song.h"
20 #include "spell/spells-status.h"
21 #include "status/action-setter.h"
22 #include "status/bad-status-setter.h"
23 #include "status/experience.h"
24 #include "system/player-type-definition.h"
25 #include "system/redrawing-flags-updater.h"
26 #include "target/target-getter.h"
27 #include "timed-effect/player-acceleration.h"
28 #include "timed-effect/timed-effects.h"
29 #include "view/display-messages.h"
30
31 /*!
32  * @brief 歌の開始を処理する / Start singing if the player is a Bard
33  * @param spell 領域魔法としてのID
34  * @param song 魔法効果のID
35  */
36 static void start_singing(PlayerType *player_ptr, SPELL_IDX spell, int32_t song)
37 {
38     /* Remember the song index */
39     set_singing_song_effect(player_ptr, song);
40
41     /* Remember the index of the spell which activated the song */
42     set_singing_song_id(player_ptr, (byte)spell);
43
44     /* Now the player is singing */
45     set_action(player_ptr, ACTION_SING);
46
47     auto &rfu = RedrawingFlagsUpdater::get_instance();
48     rfu.set_flag(StatusRecalculatingFlag::BONUS);
49     rfu.set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
50 }
51
52 /*!
53  * @brief 歌の各処理を行う
54  * @param player_ptr プレイヤーへの参照ポインタ
55  * @param spell 歌ID
56  * @param mode 処理内容 (NAME / SPELL_DESC / INFO / CAST / FAIL / SPELL_CONT / STOP)
57  * @return
58  * NAME / SPELL_DESC / INFO 時には文字列を返す.
59  * CAST / FAIL / SPELL_CONT / STOP 時は std::nullopt を返す.
60  */
61 std::optional<std::string> do_music_spell(PlayerType *player_ptr, SPELL_IDX spell, SpellProcessType mode)
62 {
63     bool name = mode == SpellProcessType::NAME;
64     bool desc = mode == SpellProcessType::DESCRIPTION;
65     bool info = mode == SpellProcessType::INFO;
66     bool cast = mode == SpellProcessType::CAST;
67     bool fail = mode == SpellProcessType::FAIL;
68     bool cont = mode == SpellProcessType::CONTNUATION;
69     bool stop = mode == SpellProcessType::STOP;
70
71     DIRECTION dir;
72     PLAYER_LEVEL plev = player_ptr->lev;
73
74     switch (spell) {
75     case 0:
76         if (name) {
77             return _("遅鈍の歌", "Song of Holding");
78         }
79         if (desc) {
80             return _("視界内の全てのモンスターを減速させる。抵抗されると無効。", "Attempts to slow all monsters in sight.");
81         }
82
83         /* Stop singing before start another */
84         if (cast || fail) {
85             stop_singing(player_ptr);
86         }
87
88         if (cast) {
89             msg_print(_("ゆっくりとしたメロディを口ずさみ始めた...", "You start humming a slow, steady melody..."));
90             start_singing(player_ptr, spell, MUSIC_SLOW);
91         }
92
93         {
94             POWER power = plev;
95
96             if (info) {
97                 return info_power(power);
98             }
99
100             if (cont) {
101                 slow_monsters(player_ptr, plev);
102             }
103         }
104         break;
105
106     case 1:
107         if (name) {
108             return _("祝福の歌", "Song of Blessing");
109         }
110         if (desc) {
111             return _("命中率とACのボーナスを得る。", "Gives a bonus to hit and AC for a few turns.");
112         }
113
114         /* Stop singing before start another */
115         if (cast || fail) {
116             stop_singing(player_ptr);
117         }
118
119         if (cast) {
120             msg_print(_("厳かなメロディを奏で始めた...", "The holy power of the Music of the Ainur enters you..."));
121             start_singing(player_ptr, spell, MUSIC_BLESS);
122         }
123
124         if (stop) {
125             if (!player_ptr->blessed) {
126                 msg_print(_("高潔な気分が消え失せた。", "The prayer has expired."));
127             }
128         }
129
130         break;
131
132     case 2:
133         if (name) {
134             return _("崩壊の音色", "Wrecking Note");
135         }
136         if (desc) {
137             return _("轟音のボルトを放つ。", "Fires a bolt of sound.");
138         }
139
140         /* Stop singing before start another */
141         if (cast || fail) {
142             stop_singing(player_ptr);
143         }
144
145         {
146             DICE_NUMBER dice = 4 + (plev - 1) / 5;
147             DICE_SID sides = 4;
148
149             if (info) {
150                 return info_damage(dice, sides, 0);
151             }
152
153             if (cast) {
154                 if (!get_aim_dir(player_ptr, &dir)) {
155                     return std::nullopt;
156                 }
157
158                 fire_bolt(player_ptr, AttributeType::SOUND, dir, damroll(dice, sides));
159             }
160         }
161         break;
162
163     case 3:
164         if (name) {
165             return _("朦朧の旋律", "Stun Pattern");
166         }
167         if (desc) {
168             return _("視界内の全てのモンスターを朦朧させる。抵抗されると無効。", "Attempts to stun all monsters in sight.");
169         }
170
171         /* Stop singing before start another */
172         if (cast || fail) {
173             stop_singing(player_ptr);
174         }
175
176         if (cast) {
177             msg_print(_("眩惑させるメロディを奏で始めた...", "You weave a pattern of sounds to bewilder and daze..."));
178             start_singing(player_ptr, spell, MUSIC_STUN);
179         }
180
181         {
182             DICE_NUMBER dice = plev / 10;
183             DICE_SID sides = 2;
184
185             if (info) {
186                 return info_power_dice(dice, sides);
187             }
188
189             if (cont) {
190                 stun_monsters(player_ptr, damroll(dice, sides));
191             }
192         }
193
194         break;
195
196     case 4:
197         if (name) {
198             return _("生命の流れ", "Flow of Life");
199         }
200         if (desc) {
201             return _("体力を少し回復させる。", "Heals HP a little.");
202         }
203
204         /* Stop singing before start another */
205         if (cast || fail) {
206             stop_singing(player_ptr);
207         }
208
209         if (cast) {
210             msg_print(_("歌を通して体に活気が戻ってきた...", "Life flows through you as you sing a song of healing..."));
211             start_singing(player_ptr, spell, MUSIC_L_LIFE);
212         }
213
214         {
215             DICE_NUMBER dice = 2;
216             DICE_SID sides = 6;
217
218             if (info) {
219                 return info_heal(dice, sides, 0);
220             }
221
222             if (cont) {
223                 hp_player(player_ptr, damroll(dice, sides));
224             }
225         }
226
227         break;
228
229     case 5:
230         if (name) {
231             return _("太陽の歌", "Song of the Sun");
232         }
233         if (desc) {
234             return _("光源が照らしている範囲か部屋全体を永久に明るくする。", "Lights up nearby area and the inside of a room permanently.");
235         }
236
237         /* Stop singing before start another */
238         if (cast || fail) {
239             stop_singing(player_ptr);
240         }
241
242         {
243             DICE_NUMBER dice = 2;
244             DICE_SID sides = plev / 2;
245             POSITION rad = plev / 10 + 1;
246
247             if (info) {
248                 return info_damage(dice, sides, 0);
249             }
250
251             if (cast) {
252                 msg_print(_("光り輝く歌が辺りを照らした。", "Your uplifting song brings brightness to dark places..."));
253                 lite_area(player_ptr, damroll(dice, sides), rad);
254             }
255         }
256         break;
257
258     case 6:
259         if (name) {
260             return _("恐怖の歌", "Song of Fear");
261         }
262         if (desc) {
263             return _("視界内の全てのモンスターを恐怖させる。抵抗されると無効。", "Attempts to scare all monsters in sight.");
264         }
265
266         /* Stop singing before start another */
267         if (cast || fail) {
268             stop_singing(player_ptr);
269         }
270
271         if (cast) {
272             msg_print(_("おどろおどろしいメロディを奏で始めた...", "You start weaving a fearful pattern..."));
273             start_singing(player_ptr, spell, MUSIC_FEAR);
274         }
275
276         {
277             POWER power = plev;
278
279             if (info) {
280                 return info_power(power);
281             }
282
283             if (cont) {
284                 project_all_los(player_ptr, AttributeType::TURN_ALL, power);
285             }
286         }
287
288         break;
289
290     case 7:
291         if (name) {
292             return _("戦いの歌", "Heroic Ballad");
293         }
294
295         if (desc) {
296             return _("ヒーロー気分になる。", "Removes fear. Gives a bonus to hit for a while. Heals you for 10 HP.");
297         }
298
299         if (cast || fail) {
300             stop_singing(player_ptr);
301         }
302
303         if (cast) {
304             msg_print(_("激しい戦いの歌を歌った...", "You start singing a song of intense fighting..."));
305
306             (void)hp_player(player_ptr, 10);
307             (void)BadStatusSetter(player_ptr).set_fear(0);
308             RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::HP);
309             start_singing(player_ptr, spell, MUSIC_HERO);
310         }
311
312         if (stop) {
313             if (!player_ptr->hero) {
314                 msg_print(_("ヒーローの気分が消え失せた。", "The heroism wears off."));
315                 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::HP);
316             }
317         }
318
319         break;
320     case 8:
321         if (name) {
322             return _("霊的知覚", "Clairaudience");
323         }
324         if (desc) {
325             return _("近くの罠/扉/"
326                      "階段を感知する。レベル15で全てのモンスター、20で財宝とアイテムを感知できるようになる。レベル25で周辺の地形を感知し、40でその階全体を永久"
327                      "に照らし、ダンジョン内のすべてのアイテムを感知する。この効果は歌い続けることで順に起こる。",
328                 "Detects traps, doors and stairs in your vicinity. And detects all monsters at level 15, treasures and items at level 20. Maps nearby area at "
329                 "level 25. Lights and know the whole level at level 40. These effects accumulate as the song continues.");
330         }
331
332         /* Stop singing before start another */
333         if (cast || fail) {
334             stop_singing(player_ptr);
335         }
336
337         if (cast) {
338             msg_print(_("静かな音楽が感覚を研ぎ澄まさせた...", "Your quiet music sharpens your sense of hearing..."));
339             /* Hack -- Initialize the turn count */
340             set_singing_count(player_ptr, 0);
341             start_singing(player_ptr, spell, MUSIC_DETECT);
342         }
343
344         {
345             POSITION rad = DETECT_RAD_DEFAULT;
346
347             if (info) {
348                 return info_radius(rad);
349             }
350
351             if (cont) {
352                 int count = get_singing_count(player_ptr);
353
354                 if (count >= 19) {
355                     wiz_lite(player_ptr, false);
356                 }
357                 if (count >= 11) {
358                     map_area(player_ptr, rad);
359                     if (plev > 39 && count < 19) {
360                         set_singing_count(player_ptr, count + 1);
361                     }
362                 }
363                 if (count >= 6) {
364                     /* There are too many hidden treasure.  So... */
365                     /* detect_treasure(rad); */
366                     detect_objects_gold(player_ptr, rad);
367                     detect_objects_normal(player_ptr, rad);
368
369                     if (plev > 24 && count < 11) {
370                         set_singing_count(player_ptr, count + 1);
371                     }
372                 }
373                 if (count >= 3) {
374                     detect_monsters_invis(player_ptr, rad);
375                     detect_monsters_normal(player_ptr, rad);
376
377                     if (plev > 19 && count < A_MAX) {
378                         set_singing_count(player_ptr, count + 1);
379                     }
380                 }
381                 detect_traps(player_ptr, rad, true);
382                 detect_doors(player_ptr, rad);
383                 detect_stairs(player_ptr, rad);
384
385                 if (plev > 14 && count < 3) {
386                     set_singing_count(player_ptr, count + 1);
387                 }
388             }
389         }
390
391         break;
392
393     case 9:
394         if (name) {
395             return _("魂の歌", "Soul Shriek");
396         }
397         if (desc) {
398             return _("視界内の全てのモンスターに対して精神攻撃を行う。", "Damages all monsters in sight with PSI damages.");
399         }
400
401         /* Stop singing before start another */
402         if (cast || fail) {
403             stop_singing(player_ptr);
404         }
405
406         if (cast) {
407             msg_print(_("精神を捻じ曲げる歌を歌った...", "You start singing a song of soul in pain..."));
408             start_singing(player_ptr, spell, MUSIC_PSI);
409         }
410
411         {
412             DICE_NUMBER dice = 1;
413             DICE_SID sides = plev * 3 / 2;
414
415             if (info) {
416                 return info_damage(dice, sides, 0);
417             }
418
419             if (cont) {
420                 project_all_los(player_ptr, AttributeType::PSI, damroll(dice, sides));
421             }
422         }
423
424         break;
425
426     case 10:
427         if (name) {
428             return _("知識の歌", "Song of Lore");
429         }
430         if (desc) {
431             return _("自分のいるマスと隣りのマスに落ちているアイテムを鑑定する。", "Identifies all items which are in the adjacent squares.");
432         }
433
434         /* Stop singing before start another */
435         if (cast || fail) {
436             stop_singing(player_ptr);
437         }
438
439         if (cast) {
440             msg_print(_("この世界の知識が流れ込んできた...", "You recall the rich lore of the world..."));
441             start_singing(player_ptr, spell, MUSIC_ID);
442         }
443
444         {
445             POSITION rad = 1;
446
447             if (info) {
448                 return info_radius(rad);
449             }
450
451             /*
452              * 歌の開始時にも効果発動:
453              * MP不足で鑑定が発動される前に歌が中断してしまうのを防止。
454              */
455             if (cont || cast) {
456                 project(player_ptr, 0, rad, player_ptr->y, player_ptr->x, 0, AttributeType::IDENTIFY, PROJECT_ITEM);
457             }
458         }
459
460         break;
461
462     case 11:
463         if (name) {
464             return _("隠遁の歌", "Hiding Tune");
465         }
466         if (desc) {
467             return _("隠密行動能力を上昇させる。", "Gives improved stealth.");
468         }
469
470         /* Stop singing before start another */
471         if (cast || fail) {
472             stop_singing(player_ptr);
473         }
474
475         if (cast) {
476             msg_print(_("あなたの姿が景色にとけこんでいった...", "Your song carries you beyond the sight of mortal eyes..."));
477             start_singing(player_ptr, spell, MUSIC_STEALTH);
478         }
479
480         if (stop) {
481             if (!player_ptr->tim_stealth) {
482                 msg_print(_("姿がはっきりと見えるようになった。", "You are no longer hidden."));
483             }
484         }
485
486         break;
487
488     case 12:
489         if (name) {
490             return _("幻影の旋律", "Illusion Pattern");
491         }
492         if (desc) {
493             return _("視界内の全てのモンスターを混乱させる。抵抗されると無効。", "Attempts to confuse all monsters in sight.");
494         }
495
496         /* Stop singing before start another */
497         if (cast || fail) {
498             stop_singing(player_ptr);
499         }
500
501         if (cast) {
502             msg_print(_("辺り一面に幻影が現れた...", "You weave a pattern of sounds to beguile and confuse..."));
503             start_singing(player_ptr, spell, MUSIC_CONF);
504         }
505
506         {
507             POWER power = plev * 2;
508
509             if (info) {
510                 return info_power(power);
511             }
512
513             if (cont) {
514                 confuse_monsters(player_ptr, power);
515             }
516         }
517
518         break;
519
520     case 13:
521         if (name) {
522             return _("破滅の叫び", "Doomcall");
523         }
524         if (desc) {
525             return _("視界内の全てのモンスターに対して轟音攻撃を行う。", "Damages all monsters in sight with booming sound.");
526         }
527
528         /* Stop singing before start another */
529         if (cast || fail) {
530             stop_singing(player_ptr);
531         }
532
533         if (cast) {
534             msg_print(_("轟音が響いた...", "The fury of the Downfall of Numenor lashes out..."));
535             start_singing(player_ptr, spell, MUSIC_SOUND);
536         }
537
538         {
539             DICE_NUMBER dice = 10 + plev / 5;
540             DICE_SID sides = 7;
541
542             if (info) {
543                 return info_damage(dice, sides, 0);
544             }
545
546             if (cont) {
547                 project_all_los(player_ptr, AttributeType::SOUND, damroll(dice, sides));
548             }
549         }
550
551         break;
552
553     case 14:
554         if (name) {
555             return _("フィリエルの歌", "Firiel's Song");
556         }
557         if (desc) {
558             return _("周囲の死体や骨を生き返す。", "Resurrects nearby corpses and skeletons. And makes them your pets.");
559         }
560
561         {
562             /* Stop singing before start another */
563             if (cast || fail) {
564                 stop_singing(player_ptr);
565             }
566
567             if (cast) {
568                 msg_print(_("生命と復活のテーマを奏で始めた...", "The themes of life and revival are woven into your song..."));
569                 animate_dead(player_ptr, 0, player_ptr->y, player_ptr->x);
570             }
571         }
572         break;
573
574     case 15:
575         if (name) {
576             return _("旅の仲間", "Fellowship Chant");
577         }
578         if (desc) {
579             return _("視界内の全てのモンスターを魅了する。抵抗されると無効。", "Attempts to charm all monsters in sight.");
580         }
581
582         /* Stop singing before start another */
583         if (cast || fail) {
584             stop_singing(player_ptr);
585         }
586
587         if (cast) {
588             msg_print(_("安らかなメロディを奏で始めた...", "You weave a slow, soothing melody of imploration..."));
589             start_singing(player_ptr, spell, MUSIC_CHARM);
590         }
591
592         {
593             DICE_NUMBER dice = 10 + plev / 15;
594             DICE_SID sides = 6;
595
596             if (info) {
597                 return info_power_dice(dice, sides);
598             }
599
600             if (cont) {
601                 charm_monsters(player_ptr, damroll(dice, sides));
602             }
603         }
604
605         break;
606
607     case 16:
608         if (name) {
609             return _("フルゥの行進曲", "Hru's March");
610         }
611         if (desc) {
612             return _("壁を掘り進む。自分の足元のアイテムは蒸発する。", "Makes you be able to burrow into walls. Objects under your feet evaporate.");
613         }
614
615         /* Stop singing before start another */
616         if (cast || fail) {
617             stop_singing(player_ptr);
618         }
619
620         if (cast) {
621             msg_print(_("粉砕するメロディを奏で始めた...", "You weave a violent pattern of sounds to break walls."));
622             start_singing(player_ptr, spell, MUSIC_WALL);
623         }
624
625         {
626             /*
627              * 歌の開始時にも効果発動:
628              * MP不足で効果が発動される前に歌が中断してしまうのを防止。
629              */
630             if (cont || cast) {
631                 project(player_ptr, 0, 0, player_ptr->y, player_ptr->x, 0, AttributeType::DISINTEGRATE, PROJECT_KILL | PROJECT_ITEM | PROJECT_HIDE);
632             }
633         }
634         break;
635
636     case 17:
637         if (name) {
638             return _("フィンロドの護り", "Finrod's Resistance");
639         }
640         if (desc) {
641             return _("酸、電撃、炎、冷気、毒に対する耐性を得る。装備による耐性に累積する。",
642                 "Gives resistance to fire, cold, electricity, acid and poison. These resistances can be added to those from equipment for more powerful "
643                 "resistances.");
644         }
645
646         /* Stop singing before start another */
647         if (cast || fail) {
648             stop_singing(player_ptr);
649         }
650
651         if (cast) {
652             msg_print(_("元素の力に対する忍耐の歌を歌った。", "You sing a song of perseverance against powers..."));
653             start_singing(player_ptr, spell, MUSIC_RESIST);
654         }
655
656         if (stop) {
657             if (!player_ptr->oppose_acid) {
658                 msg_print(_("酸への耐性が薄れた気がする。", "You feel less resistant to acid."));
659             }
660
661             if (!player_ptr->oppose_elec) {
662                 msg_print(_("電撃への耐性が薄れた気がする。", "You feel less resistant to elec."));
663             }
664
665             if (!player_ptr->oppose_fire) {
666                 msg_print(_("火への耐性が薄れた気がする。", "You feel less resistant to fire."));
667             }
668
669             if (!player_ptr->oppose_cold) {
670                 msg_print(_("冷気への耐性が薄れた気がする。", "You feel less resistant to cold."));
671             }
672
673             if (!player_ptr->oppose_pois) {
674                 msg_print(_("毒への耐性が薄れた気がする。", "You feel less resistant to pois."));
675             }
676         }
677
678         break;
679
680     case 18:
681         if (name) {
682             return _("ホビットのメロディ", "Hobbit Melodies");
683         }
684         if (desc) {
685             return _("加速する。", "Hastes you.");
686         }
687
688         /* Stop singing before start another */
689         if (cast || fail) {
690             stop_singing(player_ptr);
691         }
692
693         if (cast) {
694             msg_print(_("軽快な歌を口ずさみ始めた...", "You start singing a joyful pop song..."));
695             start_singing(player_ptr, spell, MUSIC_SPEED);
696         }
697
698         if (stop) {
699             if (!player_ptr->effects()->acceleration()->is_fast()) {
700                 msg_print(_("動きの素早さがなくなったようだ。", "You feel yourself slow down."));
701             }
702         }
703
704         break;
705
706     case 19:
707         if (name) {
708             return _("歪んだ世界", "World Contortion");
709         }
710         if (desc) {
711             return _("近くのモンスターをテレポートさせる。抵抗されると無効。", "Teleports all nearby monsters away unless resisted.");
712         }
713
714         {
715             POSITION rad = plev / 15 + 1;
716             POWER power = plev * 3 + 1;
717
718             if (info) {
719                 return info_radius(rad);
720             }
721
722             /* Stop singing before start another */
723             if (cast || fail) {
724                 stop_singing(player_ptr);
725             }
726
727             if (cast) {
728                 msg_print(_("歌が空間を歪めた...", "Reality whirls wildly as you sing a dizzying melody..."));
729                 project(player_ptr, 0, rad, player_ptr->y, player_ptr->x, power, AttributeType::AWAY_ALL, PROJECT_KILL);
730             }
731         }
732         break;
733
734     case 20:
735         if (name) {
736             return _("退散の歌", "Dispelling Chant");
737         }
738         if (desc) {
739             return _("視界内の全てのモンスターにダメージを与える。邪悪なモンスターに特に大きなダメージを与える。",
740                 "Damages all monsters in sight. Hurts evil monsters greatly.");
741         }
742
743         /* Stop singing before start another */
744         if (cast || fail) {
745             stop_singing(player_ptr);
746         }
747
748         if (cast) {
749             msg_print(_("耐えられない不協和音が敵を責め立てた...", "You cry out in an ear-wracking voice..."));
750             start_singing(player_ptr, spell, MUSIC_DISPEL);
751         }
752
753         {
754             DICE_SID m_sides = plev * 3;
755             DICE_SID e_sides = plev * 3;
756
757             if (info) {
758                 return format("%s1d%d+1d%d", KWD_DAM, m_sides, e_sides);
759             }
760
761             if (cont) {
762                 dispel_monsters(player_ptr, randint1(m_sides));
763                 dispel_evil(player_ptr, randint1(e_sides));
764             }
765         }
766         break;
767
768     case 21:
769         if (name) {
770             return _("サルマンの甘言", "The Voice of Saruman");
771         }
772         if (desc) {
773             return _("視界内の全てのモンスターを減速させ、眠らせようとする。抵抗されると無効。", "Attempts to slow and put to sleep all monsters in sight.");
774         }
775
776         /* Stop singing before start another */
777         if (cast || fail) {
778             stop_singing(player_ptr);
779         }
780
781         if (cast) {
782             msg_print(_("優しく、魅力的な歌を口ずさみ始めた...", "You start humming a gentle and attractive song..."));
783             start_singing(player_ptr, spell, MUSIC_SARUMAN);
784         }
785
786         {
787             POWER power = plev;
788
789             if (info) {
790                 return info_power(power);
791             }
792
793             if (cont) {
794                 slow_monsters(player_ptr, plev);
795                 sleep_monsters(player_ptr, plev);
796             }
797         }
798
799         break;
800
801     case 22:
802         if (name) {
803             return _("嵐の音色", "Song of the Tempest");
804         }
805         if (desc) {
806             return _("轟音のビームを放つ。", "Fires a beam of sound.");
807         }
808
809         {
810             DICE_NUMBER dice = 15 + (plev - 1) / 2;
811             DICE_SID sides = 10;
812
813             if (info) {
814                 return info_damage(dice, sides, 0);
815             }
816
817             /* Stop singing before start another */
818             if (cast || fail) {
819                 stop_singing(player_ptr);
820             }
821
822             if (cast) {
823                 if (!get_aim_dir(player_ptr, &dir)) {
824                     return std::nullopt;
825                 }
826
827                 fire_beam(player_ptr, AttributeType::SOUND, dir, damroll(dice, sides));
828             }
829         }
830         break;
831
832     case 23:
833         if (name) {
834             return _("もう一つの世界", "Ambarkanta");
835         }
836         if (desc) {
837             return _("現在の階を再構成する。", "Recreates current dungeon level.");
838         }
839
840         {
841             int base = 15;
842             DICE_SID sides = 20;
843
844             if (info) {
845                 return info_delay(base, sides);
846             }
847
848             /* Stop singing before start another */
849             if (cast || fail) {
850                 stop_singing(player_ptr);
851             }
852
853             if (cast) {
854                 msg_print(_("周囲が変化し始めた...", "You sing of the primeval shaping of Middle-earth..."));
855                 reserve_alter_reality(player_ptr, randint0(sides) + base);
856             }
857         }
858         break;
859
860     case 24:
861         if (name) {
862             return _("破壊の旋律", "Wrecking Pattern");
863         }
864         if (desc) {
865             return _(
866                 "周囲のダンジョンを揺らし、壁と床をランダムに入れ変える。", "Shakes dungeon structure, and results in random swapping of floors and walls.");
867         }
868
869         /* Stop singing before start another */
870         if (cast || fail) {
871             stop_singing(player_ptr);
872         }
873
874         if (cast) {
875             msg_print(_("破壊的な歌が響きわたった...", "You weave a pattern of sounds to contort and shatter..."));
876             start_singing(player_ptr, spell, MUSIC_QUAKE);
877         }
878
879         {
880             POSITION rad = 10;
881
882             if (info) {
883                 return info_radius(rad);
884             }
885
886             if (cont) {
887                 earthquake(player_ptr, player_ptr->y, player_ptr->x, 10, 0);
888             }
889         }
890
891         break;
892
893     case 25:
894         if (name) {
895             return _("停滞の歌", "Stationary Shriek");
896         }
897         if (desc) {
898             return _("視界内の全てのモンスターを麻痺させようとする。抵抗されると無効。", "Attempts to freeze all monsters in sight.");
899         }
900
901         /* Stop singing before start another */
902         if (cast || fail) {
903             stop_singing(player_ptr);
904         }
905
906         if (cast) {
907             msg_print(_("ゆっくりとしたメロディを奏で始めた...", "You weave a very slow pattern which is almost likely to stop..."));
908             start_singing(player_ptr, spell, MUSIC_STASIS);
909         }
910
911         {
912             POWER power = plev * 4;
913
914             if (info) {
915                 return info_power(power);
916             }
917
918             if (cont) {
919                 stasis_monsters(player_ptr, power);
920             }
921         }
922
923         break;
924
925     case 26:
926         if (name) {
927             return _("エルベレスの聖歌", "Elbereth's Chant");
928         }
929         if (desc) {
930             return _("自分のいる床の上に、モンスターが通り抜けたり召喚されたりすることができなくなるルーンを描く。",
931                 "Sets a rune on the floor beneath you. If you are on a rune, monsters cannot attack you but can try to break the rune.");
932         }
933
934         {
935             /* Stop singing before start another */
936             if (cast || fail) {
937                 stop_singing(player_ptr);
938             }
939
940             if (cast) {
941                 msg_print(_("歌が神聖な場を作り出した...", "The holy power of the Music is creating sacred field..."));
942                 create_rune_protection_one(player_ptr);
943             }
944         }
945         break;
946
947     case 27: {
948         if (name) {
949             return _("英雄の詩", "The Hero's Poem");
950         }
951
952         if (desc) {
953             return _("加速し、ヒーロー気分になり、視界内の全てのモンスターにダメージを与える。", "Hastes you. Gives heroism. Damages all monsters in sight.");
954         }
955
956         if (cast || fail) {
957             stop_singing(player_ptr);
958         }
959
960         if (cast) {
961             msg_print(_("英雄の歌を口ずさんだ...", "You chant a powerful, heroic call to arms..."));
962             (void)hp_player(player_ptr, 10);
963             (void)BadStatusSetter(player_ptr).set_fear(0);
964             RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::HP);
965             start_singing(player_ptr, spell, MUSIC_SHERO);
966         }
967
968         if (stop) {
969             if (!player_ptr->hero) {
970                 msg_print(_("ヒーローの気分が消え失せた。", "The heroism wears off."));
971                 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::HP);
972             }
973
974             if (!player_ptr->effects()->acceleration()->is_fast()) {
975                 msg_print(_("動きの素早さがなくなったようだ。", "You feel yourself slow down."));
976             }
977         }
978
979         DICE_NUMBER dice = 1;
980         DICE_SID sides = plev * 3;
981         if (info) {
982             return info_damage(dice, sides, 0);
983         }
984
985         if (cont) {
986             dispel_monsters(player_ptr, damroll(dice, sides));
987         }
988
989         break;
990     }
991     case 28: {
992         if (name) {
993             return _("ヤヴァンナの助け", "Relief of Yavanna");
994         }
995
996         if (desc) {
997             return _("強力な回復の歌で、負傷と朦朧状態も全快する。", "Powerful healing song. Also completely heals cuts and being stunned.");
998         }
999
1000         if (cast || fail) {
1001             stop_singing(player_ptr);
1002         }
1003
1004         if (cast) {
1005             msg_print(_("歌を通して体に活気が戻ってきた...", "Life flows through you as you sing the song..."));
1006             start_singing(player_ptr, spell, MUSIC_H_LIFE);
1007         }
1008
1009         auto dice = 15;
1010         auto sides = 10;
1011         if (info) {
1012             return info_heal(dice, sides, 0);
1013         }
1014
1015         if (cont) {
1016             hp_player(player_ptr, damroll(dice, sides));
1017             BadStatusSetter bss(player_ptr);
1018             (void)bss.set_stun(0);
1019             (void)bss.set_cut(0);
1020         }
1021
1022         break;
1023     }
1024     case 29:
1025         if (name) {
1026             return _("再生の歌", "Goddess's rebirth");
1027         }
1028         if (desc) {
1029             return _("すべてのステータスと経験値を回復する。", "Restores all stats and experience.");
1030         }
1031
1032         {
1033             /* Stop singing before start another */
1034             if (cast || fail) {
1035                 stop_singing(player_ptr);
1036             }
1037
1038             if (cast) {
1039                 msg_print(
1040                     _("暗黒の中に光と美をふりまいた。体が元の活力を取り戻した。", "You strew light and beauty in the dark as you sing. You feel refreshed."));
1041                 (void)restore_all_status(player_ptr);
1042                 (void)restore_level(player_ptr);
1043             }
1044         }
1045         break;
1046
1047     case 30:
1048         if (name) {
1049             return _("サウロンの魔術", "Wizardry of Sauron");
1050         }
1051         if (desc) {
1052             return _("非常に強力でごく小さい轟音の球を放つ。", "Fires an extremely powerful tiny ball of sound.");
1053         }
1054
1055         {
1056             DICE_NUMBER dice = 50 + plev;
1057             DICE_SID sides = 10;
1058             POSITION rad = 0;
1059
1060             if (info) {
1061                 return info_damage(dice, sides, 0);
1062             }
1063
1064             /* Stop singing before start another */
1065             if (cast || fail) {
1066                 stop_singing(player_ptr);
1067             }
1068
1069             if (cast) {
1070                 if (!get_aim_dir(player_ptr, &dir)) {
1071                     return std::nullopt;
1072                 }
1073
1074                 fire_ball(player_ptr, AttributeType::SOUND, dir, damroll(dice, sides), rad);
1075             }
1076         }
1077         break;
1078
1079     case 31:
1080         if (name) {
1081             return _("フィンゴルフィンの挑戦", "Fingolfin's Challenge");
1082         }
1083         if (desc) {
1084             return _("ダメージを受けなくなるバリアを張る。", "Generates a barrier which completely protects you from almost all damage.");
1085         }
1086
1087         /* Stop singing before start another */
1088         if (cast || fail) {
1089             stop_singing(player_ptr);
1090         }
1091
1092         if (cast) {
1093             msg_print(_("フィンゴルフィンの冥王への挑戦を歌った...", "You recall the valor of Fingolfin's challenge to the Dark Lord..."));
1094             auto &rfu = RedrawingFlagsUpdater::get_instance();
1095             rfu.set_flag(MainWindowRedrawingFlag::MAP);
1096             rfu.set_flag(StatusRecalculatingFlag::MONSTER_STATUSES);
1097             static constexpr auto flags = {
1098                 SubWindowRedrawingFlag::OVERHEAD,
1099                 SubWindowRedrawingFlag::DUNGEON,
1100             };
1101             rfu.set_flags(flags);
1102             start_singing(player_ptr, spell, MUSIC_INVULN);
1103         }
1104
1105         if (stop) {
1106             if (!player_ptr->invuln) {
1107                 msg_print(_("無敵ではなくなった。", "The invulnerability wears off."));
1108                 auto &rfu = RedrawingFlagsUpdater::get_instance();
1109                 rfu.set_flag(MainWindowRedrawingFlag::MAP);
1110                 rfu.set_flag(StatusRecalculatingFlag::MONSTER_STATUSES);
1111                 static constexpr auto flags = {
1112                     SubWindowRedrawingFlag::OVERHEAD,
1113                     SubWindowRedrawingFlag::DUNGEON,
1114                 };
1115                 rfu.set_flags(flags);
1116             }
1117         }
1118
1119         break;
1120     }
1121
1122     return "";
1123 }