OSDN Git Service

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