OSDN Git Service

b403f1f1d7f8fb46e526431a9e215bd0207fc634
[hengbandforosx/hengbandosx.git] / src / cmd-action / cmd-mane.cpp
1 /*!
2  * @brief ものまねの処理実装 / Imitation code
3  * @date 2014/01/14
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
6  * This software may be copied and distributed for educational, research,\n
7  * and not for profit purposes provided that this copyright and statement\n
8  * are included in all such copies.  Other copyrights may also apply.\n
9  * 2014 Deskull rearranged comment for Doxygen.\n
10  */
11
12 #include "cmd-action/cmd-mane.h"
13 #include "action/action-limited.h"
14 #include "artifact/fixed-art-types.h"
15 #include "cmd-action/cmd-spell.h"
16 #include "core/asking-player.h"
17 #include "core/player-redraw-types.h"
18 #include "core/stuff-handler.h"
19 #include "core/window-redrawer.h"
20 #include "floor/cave.h"
21 #include "floor/floor-object.h"
22 #include "game-option/disturbance-options.h"
23 #include "game-option/text-display-options.h"
24 #include "hpmp/hp-mp-processor.h"
25 #include "inventory/inventory-slot-types.h"
26 #include "main/sound-definitions-table.h"
27 #include "main/sound-of-music.h"
28 #include "mind/mind-mage.h"
29 #include "monster-floor/monster-summon.h"
30 #include "monster-floor/place-monster-types.h"
31 #include "monster-race/monster-race.h"
32 #include "monster-race/race-ability-flags.h"
33 #include "monster-race/race-flags-resistance.h"
34 #include "monster-race/race-flags1.h"
35 #include "monster/monster-describer.h"
36 #include "monster/monster-info.h"
37 #include "monster/monster-processor.h"
38 #include "monster/monster-status.h"
39 #include "mspell/monster-power-table.h"
40 #include "player-base/player-class.h"
41 #include "player-info/mane-data-type.h"
42 #include "player-status/player-energy.h"
43 #include "player/player-status-table.h"
44 #include "spell-kind/spells-launcher.h"
45 #include "spell-kind/spells-lite.h"
46 #include "spell-kind/spells-neighbor.h"
47 #include "spell-kind/spells-sight.h"
48 #include "spell-kind/spells-teleport.h"
49 #include "spell-kind/spells-world.h"
50 #include "spell/spells-status.h"
51 #include "spell/spells-summon.h"
52 #include "spell/summon-types.h"
53 #include "status/bad-status-setter.h"
54 #include "status/body-improvement.h"
55 #include "status/buff-setter.h"
56 #include "system/floor-type-definition.h"
57 #include "system/grid-type-definition.h"
58 #include "system/monster-race-definition.h"
59 #include "system/monster-type-definition.h"
60 #include "system/object-type-definition.h"
61 #include "system/player-type-definition.h"
62 #include "target/projection-path-calculator.h"
63 #include "target/target-checker.h"
64 #include "target/target-getter.h"
65 #include "target/target-setter.h"
66 #include "target/target-types.h"
67 #include "term/screen-processor.h"
68 #include "timed-effect/player-stun.h"
69 #include "timed-effect/timed-effects.h"
70 #include "util/enum-converter.h"
71 #include "util/int-char-converter.h"
72 #include "view/display-messages.h"
73
74 #include <iterator>
75
76 static int damage;
77
78 /*!
79  * @brief 受け取ったパラメータに応じてものまねの効果情報をまとめたフォーマットを返す
80  * @param p 情報を返す文字列参照ポインタ
81  * @param power ものまねの効力の種類
82  * @param dam ものまねの威力
83  */
84 static void mane_info(PlayerType *player_ptr, char *p, MonsterAbilityType power, HIT_POINT dam)
85 {
86     PLAYER_LEVEL plev = player_ptr->lev;
87
88     strcpy(p, "");
89
90     const auto power_int = enum2i(power);
91
92     if ((power_int > 2 && power_int < 41) || (power_int > 41 && power_int < 59) || (power == MonsterAbilityType::PSY_SPEAR))
93         sprintf(p, " %s%d", KWD_DAM, (int)dam);
94     else {
95         switch (power) {
96         case MonsterAbilityType::DRAIN_MANA:
97             sprintf(p, " %sd%d+%d", KWD_HEAL, plev * 3, plev);
98             break;
99         case MonsterAbilityType::HASTE:
100             sprintf(p, " %sd%d+%d", KWD_DURATION, 20 + plev, plev);
101             break;
102         case MonsterAbilityType::HEAL:
103             sprintf(p, " %s%d", KWD_HEAL, plev * 6);
104             break;
105         case MonsterAbilityType::INVULNER:
106             sprintf(p, " %sd7+7", KWD_DURATION);
107             break;
108         case MonsterAbilityType::BLINK:
109             sprintf(p, " %s10", KWD_SPHERE);
110             break;
111         case MonsterAbilityType::TPORT:
112             sprintf(p, " %s%d", KWD_SPHERE, plev * 5);
113             break;
114         case MonsterAbilityType::RAISE_DEAD:
115             sprintf(p, " %s5", KWD_SPHERE);
116             break;
117         default:
118             break;
119         }
120     }
121 }
122
123 /*!
124  * @brief どのものまねを発動するか選択する処理 /
125  * Allow user to choose a imitation.
126  * @param sn 実行したものまねのIDを返す参照ポインタ(キャンセルなどの場合-1を返す)
127  * @param baigaesi TRUEならば倍返し上の処理として行う
128  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
129  * @details
130  * If a valid spell is chosen, saves it in '*sn' and returns TRUE
131  * If the user hits escape, returns FALSE, and set '*sn' to -1
132  * If there are no legal choices, returns FALSE, and sets '*sn' to -2
133  *
134  * The "prompt" should be "cast", "recite", or "study"
135  * The "known" should be TRUE for cast/pray, FALSE for study
136  *
137  * nb: This function has a (trivial) display bug which will be obvious
138  * when you run it. It's probably easy to fix but I haven't tried,
139  * sorry.
140  */
141 static int get_mane_power(PlayerType *player_ptr, int *sn, bool baigaesi)
142 {
143     int i = 0;
144     int num = 0;
145     TERM_LEN y = 1;
146     TERM_LEN x = 18;
147     PERCENTAGE minfail = 0;
148     PLAYER_LEVEL plev = player_ptr->lev;
149     PERCENTAGE chance = 0;
150     int ask;
151     char choice;
152     char out_val[MAX_MONSTER_NAME];
153     char comment[80];
154     concptr p = _("能力", "power");
155
156     monster_power spell;
157     bool flag, redraw;
158
159     /* Assume cancelled */
160     *sn = (-1);
161
162     flag = false;
163     redraw = false;
164
165     auto mane_data = PlayerClass(player_ptr).get_specific_data<mane_data_type>();
166
167     num = mane_data->mane_list.size();
168
169     /* Build a prompt (accept all spells) */
170     (void)strnfmt(out_val, 78, _("(%c-%c, '*'で一覧, ESC) どの%sをまねますか?", "(%c-%c, *=List, ESC=exit) Use which %s? "), I2A(0), I2A(num - 1), p);
171
172     choice = always_show_list ? ESCAPE : 1;
173     while (!flag) {
174         if (choice == ESCAPE)
175             choice = ' ';
176         else if (!get_com(out_val, &choice, true))
177             break;
178
179         /* Request redraw */
180         if ((choice == ' ') || (choice == '*') || (choice == '?')) {
181             /* Show the list */
182             if (!redraw) {
183                 char psi_desc[160];
184                 redraw = true;
185                 screen_save();
186
187                 /* Display a list of spells */
188                 prt("", y, x);
189                 put_str(_("名前", "Name"), y, x + 5);
190                 put_str(_("失率 効果", "Fail Info"), y, x + 36);
191
192                 /* Dump the spells */
193                 for (i = 0; i < num; i++) {
194                     const auto &mane = mane_data->mane_list[i];
195                     /* Access the spell */
196                     spell = monster_powers.at(mane.spell);
197
198                     chance = spell.manefail;
199
200                     /* Reduce failure rate by "effective" level adjustment */
201                     if (plev > spell.level)
202                         chance -= 3 * (plev - spell.level);
203
204                     /* Reduce failure rate by INT/WIS adjustment */
205                     chance -= 3 * (adj_mag_stat[player_ptr->stat_index[spell.use_stat]] + adj_mag_stat[player_ptr->stat_index[A_DEX]] - 2) / 2;
206
207                     if (spell.manedam)
208                         chance = chance * (baigaesi ? mane.damage * 2 : mane.damage) / spell.manedam;
209
210                     chance += player_ptr->to_m_chance;
211
212                     if (player_ptr->inventory_list[INVEN_NECK].name1 == ART_GOGO_PENDANT) {
213                         chance -= 10;
214                     }
215
216                     /* Extract the minimum failure rate */
217                     minfail = adj_mag_fail[player_ptr->stat_index[spell.use_stat]];
218
219                     /* Minimum failure rate */
220                     if (chance < minfail)
221                         chance = minfail;
222
223                     auto player_stun = player_ptr->effects()->stun();
224                     chance += player_stun->get_magic_chance_penalty();
225                     if (chance > 95) {
226                         chance = 95;
227                     }
228
229                     /* Get info */
230                     mane_info(player_ptr, comment, mane.spell, (baigaesi ? mane.damage * 2 : mane.damage));
231
232                     /* Dump the spell --(-- */
233                     sprintf(psi_desc, "  %c) %-30s %3d%%%s", I2A(i), spell.name, chance, comment);
234                     prt(psi_desc, y + i + 1, x);
235                 }
236
237                 /* Clear the bottom line */
238                 prt("", y + i + 1, x);
239             }
240
241             /* Hide the list */
242             else {
243                 /* Hide list */
244                 redraw = false;
245                 screen_load();
246             }
247
248             /* Redo asking */
249             continue;
250         }
251
252         /* Note verify */
253         ask = isupper(choice);
254
255         /* Lowercase */
256         if (ask)
257             choice = (char)tolower(choice);
258
259         /* Extract request */
260         i = (islower(choice) ? A2I(choice) : -1);
261
262         /* Totally Illegal */
263         if ((i < 0) || (i >= num)) {
264             bell();
265             continue;
266         }
267
268         /* Save the spell index */
269         spell = monster_powers.at(mane_data->mane_list[i].spell);
270
271         /* Verify it */
272         if (ask) {
273             char tmp_val[160];
274
275             /* Prompt */
276             (void)strnfmt(tmp_val, 78, _("%sをまねますか?", "Use %s? "), spell.name);
277
278             /* Belay that order */
279             if (!get_check(tmp_val))
280                 continue;
281         }
282
283         /* Stop the loop */
284         flag = true;
285     }
286     if (redraw)
287         screen_load();
288
289     player_ptr->window_flags |= (PW_SPELL);
290     handle_stuff(player_ptr);
291
292     /* Abort if needed */
293     if (!flag)
294         return false;
295
296     /* Save the choice */
297     (*sn) = i;
298
299     damage = (baigaesi ? mane_data->mane_list[i].damage * 2 : mane_data->mane_list[i].damage);
300
301     /* Success */
302     return true;
303 }
304
305 /*!
306  * @brief ものまね処理の発動 /
307  * do_cmd_cast calls this function if the player's class is 'imitator'.
308  * @param player_ptr プレイヤーへの参照ポインタ
309  * @param spell 発動するモンスター攻撃のID
310  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
311  */
312 static bool use_mane(PlayerType *player_ptr, MonsterAbilityType spell)
313 {
314     DIRECTION dir;
315     PLAYER_LEVEL plev = player_ptr->lev;
316     BIT_FLAGS mode = (PM_ALLOW_GROUP | PM_FORCE_PET);
317     BIT_FLAGS u_mode = 0L;
318
319     if (randint1(50 + plev) < plev / 10)
320         u_mode = PM_ALLOW_UNIQUE;
321
322     /* spell code */
323     switch (spell) {
324     case MonsterAbilityType::SHRIEK:
325         msg_print(_("かん高い金切り声をあげた。", "You make a high pitched shriek."));
326         aggravate_monsters(player_ptr, 0);
327         break;
328
329     case MonsterAbilityType::XXX1:
330         break;
331
332     case MonsterAbilityType::DISPEL: {
333         MONSTER_IDX m_idx;
334
335         if (!target_set(player_ptr, TARGET_KILL))
336             return false;
337         m_idx = player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx;
338         if (!m_idx)
339             break;
340         if (!player_has_los_bold(player_ptr, target_row, target_col))
341             break;
342         if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col))
343             break;
344         dispel_monster_status(player_ptr, m_idx);
345         break;
346     }
347
348     case MonsterAbilityType::ROCKET:
349         if (!get_aim_dir(player_ptr, &dir))
350             return false;
351         else
352             msg_print(_("ロケットを発射した。", "You fire a rocket."));
353         fire_rocket(player_ptr, AttributeType::ROCKET, dir, damage, 2);
354         break;
355
356     case MonsterAbilityType::SHOOT:
357         if (!get_aim_dir(player_ptr, &dir))
358             return false;
359         else
360             msg_print(_("矢を放った。", "You fire an arrow."));
361         fire_bolt(player_ptr, AttributeType::MONSTER_SHOOT, dir, damage);
362         break;
363
364     case MonsterAbilityType::XXX2:
365         break;
366
367     case MonsterAbilityType::XXX3:
368         break;
369
370     case MonsterAbilityType::XXX4:
371         break;
372
373     case MonsterAbilityType::BR_ACID:
374         if (!get_aim_dir(player_ptr, &dir))
375             return false;
376         else
377             msg_print(_("酸のブレスを吐いた。", "You breathe acid."));
378         fire_breath(player_ptr, AttributeType::ACID, dir, damage, (plev > 35 ? 3 : 2));
379         break;
380
381     case MonsterAbilityType::BR_ELEC:
382         if (!get_aim_dir(player_ptr, &dir))
383             return false;
384         else
385             msg_print(_("稲妻のブレスを吐いた。", "You breathe lightning."));
386         fire_breath(player_ptr, AttributeType::ELEC, dir, damage, (plev > 35 ? 3 : 2));
387         break;
388
389     case MonsterAbilityType::BR_FIRE:
390         if (!get_aim_dir(player_ptr, &dir))
391             return false;
392         else
393             msg_print(_("火炎のブレスを吐いた。", "You breathe fire."));
394         fire_breath(player_ptr, AttributeType::FIRE, dir, damage, (plev > 35 ? 3 : 2));
395         break;
396
397     case MonsterAbilityType::BR_COLD:
398         if (!get_aim_dir(player_ptr, &dir))
399             return false;
400         else
401             msg_print(_("冷気のブレスを吐いた。", "You breathe frost."));
402         fire_breath(player_ptr, AttributeType::COLD, dir, damage, (plev > 35 ? 3 : 2));
403         break;
404
405     case MonsterAbilityType::BR_POIS:
406         if (!get_aim_dir(player_ptr, &dir))
407             return false;
408         else
409             msg_print(_("ガスのブレスを吐いた。", "You breathe gas."));
410         fire_breath(player_ptr, AttributeType::POIS, dir, damage, (plev > 35 ? 3 : 2));
411         break;
412
413     case MonsterAbilityType::BR_NETH:
414         if (!get_aim_dir(player_ptr, &dir))
415             return false;
416         else
417             msg_print(_("地獄のブレスを吐いた。", "You breathe nether."));
418         fire_breath(player_ptr, AttributeType::NETHER, dir, damage, (plev > 35 ? 3 : 2));
419         break;
420
421     case MonsterAbilityType::BR_LITE:
422         if (!get_aim_dir(player_ptr, &dir))
423             return false;
424         else
425             msg_print(_("閃光のブレスを吐いた。", "You breathe light."));
426         fire_breath(player_ptr, AttributeType::LITE, dir, damage, (plev > 35 ? 3 : 2));
427         break;
428
429     case MonsterAbilityType::BR_DARK:
430         if (!get_aim_dir(player_ptr, &dir))
431             return false;
432         else
433             msg_print(_("暗黒のブレスを吐いた。", "You breathe darkness."));
434         fire_breath(player_ptr, AttributeType::DARK, dir, damage, (plev > 35 ? 3 : 2));
435         break;
436
437     case MonsterAbilityType::BR_CONF:
438         if (!get_aim_dir(player_ptr, &dir))
439             return false;
440         else
441             msg_print(_("混乱のブレスを吐いた。", "You breathe confusion."));
442         fire_breath(player_ptr, AttributeType::CONFUSION, dir, damage, (plev > 35 ? 3 : 2));
443         break;
444
445     case MonsterAbilityType::BR_SOUN:
446         if (!get_aim_dir(player_ptr, &dir))
447             return false;
448         else
449             msg_print(_("轟音のブレスを吐いた。", "You breathe sound."));
450         fire_breath(player_ptr, AttributeType::SOUND, dir, damage, (plev > 35 ? 3 : 2));
451         break;
452
453     case MonsterAbilityType::BR_CHAO:
454         if (!get_aim_dir(player_ptr, &dir))
455             return false;
456         else
457             msg_print(_("カオスのブレスを吐いた。", "You breathe chaos."));
458         fire_breath(player_ptr, AttributeType::CHAOS, dir, damage, (plev > 35 ? 3 : 2));
459         break;
460
461     case MonsterAbilityType::BR_DISE:
462         if (!get_aim_dir(player_ptr, &dir))
463             return false;
464         else
465             msg_print(_("劣化のブレスを吐いた。", "You breathe disenchantment."));
466         fire_breath(player_ptr, AttributeType::DISENCHANT, dir, damage, (plev > 35 ? 3 : 2));
467         break;
468
469     case MonsterAbilityType::BR_NEXU:
470         if (!get_aim_dir(player_ptr, &dir))
471             return false;
472         else
473             msg_print(_("因果混乱のブレスを吐いた。", "You breathe nexus."));
474         fire_breath(player_ptr, AttributeType::NEXUS, dir, damage, (plev > 35 ? 3 : 2));
475         break;
476
477     case MonsterAbilityType::BR_TIME:
478         if (!get_aim_dir(player_ptr, &dir))
479             return false;
480         else
481             msg_print(_("時間逆転のブレスを吐いた。", "You breathe time."));
482         fire_breath(player_ptr, AttributeType::TIME, dir, damage, (plev > 35 ? 3 : 2));
483         break;
484
485     case MonsterAbilityType::BR_INER:
486         if (!get_aim_dir(player_ptr, &dir))
487             return false;
488         else
489             msg_print(_("遅鈍のブレスを吐いた。", "You breathe inertia."));
490         fire_breath(player_ptr, AttributeType::INERTIAL, dir, damage, (plev > 35 ? 3 : 2));
491         break;
492
493     case MonsterAbilityType::BR_GRAV:
494         if (!get_aim_dir(player_ptr, &dir))
495             return false;
496         else
497             msg_print(_("重力のブレスを吐いた。", "You breathe gravity."));
498         fire_breath(player_ptr, AttributeType::GRAVITY, dir, damage, (plev > 35 ? 3 : 2));
499         break;
500
501     case MonsterAbilityType::BR_SHAR:
502         if (!get_aim_dir(player_ptr, &dir))
503             return false;
504         else
505             msg_print(_("破片のブレスを吐いた。", "You breathe shards."));
506         fire_breath(player_ptr, AttributeType::SHARDS, dir, damage, (plev > 35 ? 3 : 2));
507         break;
508
509     case MonsterAbilityType::BR_PLAS:
510         if (!get_aim_dir(player_ptr, &dir))
511             return false;
512         else
513             msg_print(_("プラズマのブレスを吐いた。", "You breathe plasma."));
514
515         fire_breath(player_ptr, AttributeType::PLASMA, dir, damage, (plev > 35 ? 3 : 2));
516         break;
517
518     case MonsterAbilityType::BR_FORC:
519         if (!get_aim_dir(player_ptr, &dir))
520             return false;
521         else
522             msg_print(_("フォースのブレスを吐いた。", "You breathe force."));
523
524         fire_breath(player_ptr, AttributeType::FORCE, dir, damage, (plev > 35 ? 3 : 2));
525         break;
526
527     case MonsterAbilityType::BR_MANA:
528         if (!get_aim_dir(player_ptr, &dir))
529             return false;
530         else
531             msg_print(_("魔力のブレスを吐いた。", "You breathe mana."));
532
533         fire_breath(player_ptr, AttributeType::MANA, dir, damage, (plev > 35 ? 3 : 2));
534         break;
535
536     case MonsterAbilityType::BA_NUKE:
537         if (!get_aim_dir(player_ptr, &dir))
538             return false;
539         else
540             msg_print(_("放射能球を放った。", "You cast a ball of radiation."));
541
542         fire_ball(player_ptr, AttributeType::NUKE, dir, damage, 2);
543         break;
544
545     case MonsterAbilityType::BR_NUKE:
546         if (!get_aim_dir(player_ptr, &dir))
547             return false;
548         else
549             msg_print(_("放射性廃棄物のブレスを吐いた。", "You breathe toxic waste."));
550
551         fire_breath(player_ptr, AttributeType::NUKE, dir, damage, (plev > 35 ? 3 : 2));
552         break;
553
554     case MonsterAbilityType::BA_CHAO:
555         if (!get_aim_dir(player_ptr, &dir))
556             return false;
557         else
558             msg_print(_("純ログルスを放った。", "You invoke a raw Logrus."));
559
560         fire_ball(player_ptr, AttributeType::CHAOS, dir, damage, 4);
561         break;
562     case MonsterAbilityType::BR_DISI:
563         if (!get_aim_dir(player_ptr, &dir))
564             return false;
565         else
566             msg_print(_("分解のブレスを吐いた。", "You breathe disintegration."));
567
568         fire_breath(player_ptr, AttributeType::DISINTEGRATE, dir, damage, (plev > 35 ? 3 : 2));
569         break;
570     case MonsterAbilityType::BA_ACID:
571         if (!get_aim_dir(player_ptr, &dir))
572             return false;
573         else
574             msg_print(_("アシッド・ボールの呪文を唱えた。", "You cast an acid ball."));
575
576         fire_ball(player_ptr, AttributeType::ACID, dir, damage, 2);
577         break;
578     case MonsterAbilityType::BA_ELEC:
579         if (!get_aim_dir(player_ptr, &dir))
580             return false;
581         else
582             msg_print(_("サンダー・ボールの呪文を唱えた。", "You cast a lightning ball."));
583
584         fire_ball(player_ptr, AttributeType::ELEC, dir, damage, 2);
585         break;
586     case MonsterAbilityType::BA_FIRE:
587         if (!get_aim_dir(player_ptr, &dir))
588             return false;
589         else
590             msg_print(_("ファイア・ボールの呪文を唱えた。", "You cast a fire ball."));
591
592         fire_ball(player_ptr, AttributeType::FIRE, dir, damage, 2);
593         break;
594     case MonsterAbilityType::BA_COLD:
595         if (!get_aim_dir(player_ptr, &dir))
596             return false;
597         else
598             msg_print(_("アイス・ボールの呪文を唱えた。", "You cast a frost ball."));
599
600         fire_ball(player_ptr, AttributeType::COLD, dir, damage, 2);
601         break;
602     case MonsterAbilityType::BA_POIS:
603         if (!get_aim_dir(player_ptr, &dir))
604             return false;
605         else
606             msg_print(_("悪臭雲の呪文を唱えた。", "You cast a stinking cloud."));
607
608         fire_ball(player_ptr, AttributeType::POIS, dir, damage, 2);
609         break;
610     case MonsterAbilityType::BA_NETH:
611         if (!get_aim_dir(player_ptr, &dir))
612             return false;
613         else
614             msg_print(_("地獄球の呪文を唱えた。", "You cast a nether ball."));
615
616         fire_ball(player_ptr, AttributeType::NETHER, dir, damage, 2);
617         break;
618     case MonsterAbilityType::BA_WATE:
619         if (!get_aim_dir(player_ptr, &dir))
620             return false;
621         else
622             msg_print(_("流れるような身振りをした。", "You gesture fluidly."));
623
624         fire_ball(player_ptr, AttributeType::WATER, dir, damage, 4);
625         break;
626     case MonsterAbilityType::BA_MANA:
627         if (!get_aim_dir(player_ptr, &dir))
628             return false;
629         else
630             msg_print(_("魔力の嵐の呪文を念じた。", "You invoke a mana storm."));
631
632         fire_ball(player_ptr, AttributeType::MANA, dir, damage, 4);
633         break;
634     case MonsterAbilityType::BA_DARK:
635         if (!get_aim_dir(player_ptr, &dir))
636             return false;
637         else
638             msg_print(_("暗黒の嵐の呪文を念じた。", "You invoke a darkness storm."));
639
640         fire_ball(player_ptr, AttributeType::DARK, dir, damage, 4);
641         break;
642     case MonsterAbilityType::DRAIN_MANA:
643         if (!get_aim_dir(player_ptr, &dir))
644             return false;
645         fire_ball_hide(player_ptr, AttributeType::DRAIN_MANA, dir, randint1(plev * 3) + plev, 0);
646         break;
647     case MonsterAbilityType::MIND_BLAST:
648         if (!get_aim_dir(player_ptr, &dir))
649             return false;
650         fire_ball_hide(player_ptr, AttributeType::MIND_BLAST, dir, damage, 0);
651         break;
652     case MonsterAbilityType::BRAIN_SMASH:
653         if (!get_aim_dir(player_ptr, &dir))
654             return false;
655         fire_ball_hide(player_ptr, AttributeType::BRAIN_SMASH, dir, damage, 0);
656         break;
657     case MonsterAbilityType::CAUSE_1:
658         if (!get_aim_dir(player_ptr, &dir))
659             return false;
660         fire_ball_hide(player_ptr, AttributeType::CAUSE_1, dir, damage, 0);
661         break;
662     case MonsterAbilityType::CAUSE_2:
663         if (!get_aim_dir(player_ptr, &dir))
664             return false;
665         fire_ball_hide(player_ptr, AttributeType::CAUSE_2, dir, damage, 0);
666         break;
667     case MonsterAbilityType::CAUSE_3:
668         if (!get_aim_dir(player_ptr, &dir))
669             return false;
670         fire_ball_hide(player_ptr, AttributeType::CAUSE_3, dir, damage, 0);
671         break;
672     case MonsterAbilityType::CAUSE_4:
673         if (!get_aim_dir(player_ptr, &dir))
674             return false;
675         fire_ball_hide(player_ptr, AttributeType::CAUSE_4, dir, damage, 0);
676         break;
677     case MonsterAbilityType::BO_ACID:
678         if (!get_aim_dir(player_ptr, &dir))
679             return false;
680         else
681             msg_print(_("アシッド・ボルトの呪文を唱えた。", "You cast an acid bolt."));
682
683         fire_bolt(player_ptr, AttributeType::ACID, dir, damage);
684         break;
685     case MonsterAbilityType::BO_ELEC:
686         if (!get_aim_dir(player_ptr, &dir))
687             return false;
688         else
689             msg_print(_("サンダー・ボルトの呪文を唱えた。", "You cast a lightning bolt."));
690
691         fire_bolt(player_ptr, AttributeType::ELEC, dir, damage);
692         break;
693     case MonsterAbilityType::BO_FIRE:
694         if (!get_aim_dir(player_ptr, &dir))
695             return false;
696         else
697             msg_print(_("ファイア・ボルトの呪文を唱えた。", "You cast a fire bolt."));
698
699         fire_bolt(player_ptr, AttributeType::FIRE, dir, damage);
700         break;
701     case MonsterAbilityType::BO_COLD:
702         if (!get_aim_dir(player_ptr, &dir))
703             return false;
704         else
705             msg_print(_("アイス・ボルトの呪文を唱えた。", "You cast a frost bolt."));
706
707         fire_bolt(player_ptr, AttributeType::COLD, dir, damage);
708         break;
709     case MonsterAbilityType::BA_LITE:
710         if (!get_aim_dir(player_ptr, &dir))
711             return false;
712         else
713             msg_print(_("スターバーストの呪文を念じた。", "You invoke a starburst."));
714
715         fire_ball(player_ptr, AttributeType::LITE, dir, damage, 4);
716         break;
717     case MonsterAbilityType::BO_NETH:
718         if (!get_aim_dir(player_ptr, &dir))
719             return false;
720         else
721             msg_print(_("地獄の矢の呪文を唱えた。", "You cast a nether bolt."));
722
723         fire_bolt(player_ptr, AttributeType::NETHER, dir, damage);
724         break;
725     case MonsterAbilityType::BO_WATE:
726         if (!get_aim_dir(player_ptr, &dir))
727             return false;
728         else
729             msg_print(_("ウォーター・ボルトの呪文を唱えた。", "You cast a water bolt."));
730
731         fire_bolt(player_ptr, AttributeType::WATER, dir, damage);
732         break;
733     case MonsterAbilityType::BO_MANA:
734         if (!get_aim_dir(player_ptr, &dir))
735             return false;
736         else
737             msg_print(_("魔力の矢の呪文を唱えた。", "You cast a mana bolt."));
738
739         fire_bolt(player_ptr, AttributeType::MANA, dir, damage);
740         break;
741     case MonsterAbilityType::BO_PLAS:
742         if (!get_aim_dir(player_ptr, &dir))
743             return false;
744         else
745             msg_print(_("プラズマ・ボルトの呪文を唱えた。", "You cast a plasma bolt."));
746
747         fire_bolt(player_ptr, AttributeType::PLASMA, dir, damage);
748         break;
749     case MonsterAbilityType::BO_ICEE:
750         if (!get_aim_dir(player_ptr, &dir))
751             return false;
752         else
753             msg_print(_("極寒の矢の呪文を唱えた。", "You cast a ice bolt."));
754
755         fire_bolt(player_ptr, AttributeType::ICE, dir, damage);
756         break;
757     case MonsterAbilityType::MISSILE:
758         if (!get_aim_dir(player_ptr, &dir))
759             return false;
760         else
761             msg_print(_("マジック・ミサイルの呪文を唱えた。", "You cast a magic missile."));
762
763         fire_bolt(player_ptr, AttributeType::MISSILE, dir, damage);
764         break;
765     case MonsterAbilityType::SCARE:
766         if (!get_aim_dir(player_ptr, &dir))
767             return false;
768         else
769             msg_print(_("恐ろしげな幻覚を作り出した。", "You cast a fearful illusion."));
770
771         fear_monster(player_ptr, dir, plev + 10);
772         break;
773     case MonsterAbilityType::BLIND:
774         if (!get_aim_dir(player_ptr, &dir))
775             return false;
776         confuse_monster(player_ptr, dir, plev * 2);
777         break;
778     case MonsterAbilityType::CONF:
779         if (!get_aim_dir(player_ptr, &dir))
780             return false;
781         else
782             msg_print(_("誘惑的な幻覚をつくり出した。", "You cast a mesmerizing illusion."));
783
784         confuse_monster(player_ptr, dir, plev * 2);
785         break;
786     case MonsterAbilityType::SLOW:
787         if (!get_aim_dir(player_ptr, &dir))
788             return false;
789         slow_monster(player_ptr, dir, plev);
790         break;
791     case MonsterAbilityType::HOLD:
792         if (!get_aim_dir(player_ptr, &dir))
793             return false;
794         sleep_monster(player_ptr, dir, plev);
795         break;
796     case MonsterAbilityType::HASTE:
797         (void)set_fast(player_ptr, randint1(20 + plev) + plev, false);
798         break;
799     case MonsterAbilityType::HAND_DOOM: {
800         if (!get_aim_dir(player_ptr, &dir))
801             return false;
802         else
803             msg_print(_("<破滅の手>を放った!", "You invoke the Hand of Doom!"));
804
805         fire_ball_hide(player_ptr, AttributeType::HAND_DOOM, dir, 200, 0);
806         break;
807     }
808     case MonsterAbilityType::HEAL: {
809         msg_print(_("自分の傷に念を集中した。", "You concentrate on your wounds!"));
810         (void)hp_player(player_ptr, plev * 6);
811         BadStatusSetter bss(player_ptr);
812         (void)bss.stun(0);
813         (void)bss.cut(0);
814         break;
815     }
816     case MonsterAbilityType::INVULNER:
817         msg_print(_("無傷の球の呪文を唱えた。", "You cast a Globe of Invulnerability."));
818         (void)set_invuln(player_ptr, randint1(7) + 7, false);
819         break;
820     case MonsterAbilityType::BLINK:
821         teleport_player(player_ptr, 10, TELEPORT_SPONTANEOUS);
822         break;
823     case MonsterAbilityType::TPORT:
824         teleport_player(player_ptr, plev * 5, TELEPORT_SPONTANEOUS);
825         break;
826     case MonsterAbilityType::WORLD:
827         (void)time_walk(player_ptr);
828         break;
829     case MonsterAbilityType::SPECIAL:
830         break;
831     case MonsterAbilityType::TELE_TO: {
832         monster_type *m_ptr;
833         monster_race *r_ptr;
834         GAME_TEXT m_name[MAX_NLEN];
835
836         if (!target_set(player_ptr, TARGET_KILL))
837             return false;
838         if (!player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx)
839             break;
840         if (!player_has_los_bold(player_ptr, target_row, target_col))
841             break;
842         if (!projectable(player_ptr, player_ptr->y, player_ptr->x, target_row, target_col))
843             break;
844         m_ptr = &player_ptr->current_floor_ptr->m_list[player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx];
845         r_ptr = &r_info[m_ptr->r_idx];
846         monster_desc(player_ptr, m_name, m_ptr, 0);
847         if (r_ptr->flagsr & RFR_RES_TELE) {
848             if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL)) {
849                 if (is_original_ap_and_seen(player_ptr, m_ptr))
850                     r_ptr->r_flagsr |= RFR_RES_TELE;
851                 msg_format(_("%sには効果がなかった!", "%s is unaffected!"), m_name);
852
853                 break;
854             } else if (r_ptr->level > randint1(100)) {
855                 if (is_original_ap_and_seen(player_ptr, m_ptr))
856                     r_ptr->r_flagsr |= RFR_RES_TELE;
857                 msg_format(_("%sには耐性がある!", "%s resists!"), m_name);
858
859                 break;
860             }
861         }
862         msg_format(_("%sを引き戻した。", "You command %s to return."), m_name);
863
864         teleport_monster_to(
865             player_ptr, player_ptr->current_floor_ptr->grid_array[target_row][target_col].m_idx, player_ptr->y, player_ptr->x, 100, TELEPORT_PASSIVE);
866         break;
867     }
868     case MonsterAbilityType::TELE_AWAY:
869         if (!get_aim_dir(player_ptr, &dir))
870             return false;
871
872         (void)fire_beam(player_ptr, AttributeType::AWAY_ALL, dir, plev);
873         break;
874
875     case MonsterAbilityType::TELE_LEVEL:
876         return teleport_level_other(player_ptr);
877         break;
878
879     case MonsterAbilityType::PSY_SPEAR:
880         if (!get_aim_dir(player_ptr, &dir))
881             return false;
882         else
883             msg_print(_("光の剣を放った。", "You throw a psycho-spear."));
884         (void)fire_beam(player_ptr, AttributeType::PSY_SPEAR, dir, damage);
885         break;
886
887     case MonsterAbilityType::DARKNESS:
888         msg_print(_("暗闇の中で手を振った。", "You gesture in shadow."));
889         (void)unlite_area(player_ptr, 10, 3);
890         break;
891
892     case MonsterAbilityType::TRAPS:
893         if (!target_set(player_ptr, TARGET_KILL))
894             return false;
895         msg_print(_("呪文を唱えて邪悪に微笑んだ。", "You cast a spell and cackle evilly."));
896         trap_creation(player_ptr, target_row, target_col);
897         break;
898     case MonsterAbilityType::FORGET:
899         msg_print(_("しかし何も起きなかった。", "Nothing happens."));
900         break;
901     case MonsterAbilityType::RAISE_DEAD:
902         msg_print(_("死者復活の呪文を唱えた。", "You animate the dead."));
903         (void)animate_dead(player_ptr, 0, player_ptr->y, player_ptr->x);
904         break;
905     case MonsterAbilityType::S_KIN: {
906         int k;
907         if (!target_set(player_ptr, TARGET_KILL))
908             return false;
909
910         msg_print(_("援軍を召喚した。", "You summon minions."));
911         for (k = 0; k < 4; k++) {
912             (void)summon_kin_player(player_ptr, plev, target_row, target_col, (PM_FORCE_PET | PM_ALLOW_GROUP));
913         }
914         break;
915     }
916     case MonsterAbilityType::S_CYBER: {
917         int k;
918         int max_cyber = (player_ptr->current_floor_ptr->dun_level / 50) + randint1(3);
919         if (!target_set(player_ptr, TARGET_KILL))
920             return false;
921         msg_print(_("サイバーデーモンを召喚した!", "You summon Cyberdemons!"));
922         if (max_cyber > 4)
923             max_cyber = 4;
924         for (k = 0; k < max_cyber; k++)
925             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_CYBER, mode);
926         break;
927     }
928     case MonsterAbilityType::S_MONSTER: {
929         int k;
930         if (!target_set(player_ptr, TARGET_KILL))
931             return false;
932         msg_print(_("仲間を召喚した。", "You summon help."));
933         for (k = 0; k < 1; k++)
934             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_NONE, (mode | u_mode));
935         break;
936     }
937     case MonsterAbilityType::S_MONSTERS: {
938         int k;
939         if (!target_set(player_ptr, TARGET_KILL))
940             return false;
941         msg_print(_("モンスターを召喚した!", "You summon monsters!"));
942         for (k = 0; k < 6; k++)
943             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_NONE, (mode | u_mode));
944         break;
945     }
946     case MonsterAbilityType::S_ANT: {
947         int k;
948         if (!target_set(player_ptr, TARGET_KILL))
949             return false;
950         msg_print(_("アリを召喚した。", "You summon ants."));
951         for (k = 0; k < 6; k++)
952             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_ANT, mode);
953         break;
954     }
955     case MonsterAbilityType::S_SPIDER: {
956         int k;
957         if (!target_set(player_ptr, TARGET_KILL))
958             return false;
959         msg_print(_("蜘蛛を召喚した。", "You summon spiders."));
960         for (k = 0; k < 6; k++)
961             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_SPIDER, mode);
962         break;
963     }
964     case MonsterAbilityType::S_HOUND: {
965         int k;
966         if (!target_set(player_ptr, TARGET_KILL))
967             return false;
968         msg_print(_("ハウンドを召喚した。", "You summon hounds."));
969         for (k = 0; k < 4; k++)
970             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HOUND, mode);
971         break;
972     }
973     case MonsterAbilityType::S_HYDRA: {
974         int k;
975         if (!target_set(player_ptr, TARGET_KILL))
976             return false;
977         msg_print(_("ヒドラを召喚した。", "You summon hydras."));
978         for (k = 0; k < 4; k++)
979             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HYDRA, mode);
980         break;
981     }
982     case MonsterAbilityType::S_ANGEL: {
983         int k;
984         if (!target_set(player_ptr, TARGET_KILL))
985             return false;
986         msg_print(_("天使を召喚した!", "You summon an angel!"));
987         for (k = 0; k < 1; k++)
988             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_ANGEL, mode);
989         break;
990     }
991     case MonsterAbilityType::S_DEMON: {
992         int k;
993         if (!target_set(player_ptr, TARGET_KILL))
994             return false;
995         msg_print(_("混沌の宮廷から悪魔を召喚した!", "You summon a demon from the Courts of Chaos!"));
996         for (k = 0; k < 1; k++)
997             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_DEMON, (mode | u_mode));
998         break;
999     }
1000     case MonsterAbilityType::S_UNDEAD: {
1001         int k;
1002         if (!target_set(player_ptr, TARGET_KILL))
1003             return false;
1004         msg_print(_("アンデッドの強敵を召喚した!", "You summon an undead adversary!"));
1005         for (k = 0; k < 1; k++)
1006             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_UNDEAD, (mode | u_mode));
1007         break;
1008     }
1009     case MonsterAbilityType::S_DRAGON: {
1010         int k;
1011         if (!target_set(player_ptr, TARGET_KILL))
1012             return false;
1013         msg_print(_("ドラゴンを召喚した!", "You summon a dragon!"));
1014         for (k = 0; k < 1; k++)
1015             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_DRAGON, (mode | u_mode));
1016         break;
1017     }
1018     case MonsterAbilityType::S_HI_UNDEAD: {
1019         int k;
1020         if (!target_set(player_ptr, TARGET_KILL))
1021             return false;
1022         msg_print(_("強力なアンデッドを召喚した!", "You summon greater undead!"));
1023         for (k = 0; k < 6; k++)
1024             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
1025         break;
1026     }
1027     case MonsterAbilityType::S_HI_DRAGON: {
1028         int k;
1029         if (!target_set(player_ptr, TARGET_KILL))
1030             return false;
1031         msg_print(_("古代ドラゴンを召喚した!", "You summon ancient dragons!"));
1032         for (k = 0; k < 4; k++)
1033             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_DRAGON, (mode | u_mode));
1034         break;
1035     }
1036     case MonsterAbilityType::S_AMBERITES: {
1037         int k;
1038         if (!target_set(player_ptr, TARGET_KILL))
1039             return false;
1040         msg_print(_("アンバーの王族を召喚した!", "You summon Lords of Amber!"));
1041         for (k = 0; k < 4; k++)
1042             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_AMBERITES, (mode | PM_ALLOW_UNIQUE));
1043         break;
1044     }
1045     case MonsterAbilityType::S_UNIQUE: {
1046         int k, count = 0;
1047         if (!target_set(player_ptr, TARGET_KILL))
1048             return false;
1049         msg_print(_("特別な強敵を召喚した!", "You summon special opponents!"));
1050         for (k = 0; k < 4; k++)
1051             if (summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE)))
1052                 count++;
1053         for (k = count; k < 4; k++)
1054             summon_specific(player_ptr, -1, target_row, target_col, plev, SUMMON_HI_UNDEAD, (mode | u_mode));
1055         break;
1056     }
1057     default:
1058         msg_print("hoge?");
1059     }
1060
1061     return true;
1062 }
1063
1064 /*!
1065  * @brief ものまねコマンドのメインルーチン /
1066  * do_cmd_cast calls this function if the player's class is 'imitator'.
1067  * @param baigaesi TRUEならば倍返し上の処理として行う
1068  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
1069  * @details
1070  * If a valid spell is chosen, saves it in '*sn' and returns TRUE
1071  * If the user hits escape, returns FALSE, and set '*sn' to -1
1072  * If there are no legal choices, returns FALSE, and sets '*sn' to -2
1073  *
1074  * The "prompt" should be "cast", "recite", or "study"
1075  * The "known" should be TRUE for cast/pray, FALSE for study
1076  *
1077  * nb: This function has a (trivial) display bug which will be obvious
1078  * when you run it. It's probably easy to fix but I haven't tried,
1079  * sorry.
1080  */
1081 bool do_cmd_mane(PlayerType *player_ptr, bool baigaesi)
1082 {
1083     int n = 0;
1084     PERCENTAGE chance;
1085     PERCENTAGE minfail = 0;
1086     PLAYER_LEVEL plev = player_ptr->lev;
1087     monster_power spell;
1088     bool cast;
1089
1090     if (cmd_limit_confused(player_ptr))
1091         return false;
1092
1093     auto mane_data = PlayerClass(player_ptr).get_specific_data<mane_data_type>();
1094
1095     if (mane_data->mane_list.empty()) {
1096         msg_print(_("まねられるものが何もない!", "You don't remember any action!"));
1097         return false;
1098     }
1099
1100     if (!get_mane_power(player_ptr, &n, baigaesi))
1101         return false;
1102
1103     spell = monster_powers.at(mane_data->mane_list[n].spell);
1104
1105     /* Spell failure chance */
1106     chance = spell.manefail;
1107
1108     /* Reduce failure rate by "effective" level adjustment */
1109     if (plev > spell.level)
1110         chance -= 3 * (plev - spell.level);
1111
1112     /* Reduce failure rate by 1 stat and DEX adjustment */
1113     chance -= 3 * (adj_mag_stat[player_ptr->stat_index[spell.use_stat]] + adj_mag_stat[player_ptr->stat_index[A_DEX]] - 2) / 2;
1114
1115     if (spell.manedam)
1116         chance = chance * damage / spell.manedam;
1117
1118     chance += player_ptr->to_m_chance;
1119
1120     /* Extract the minimum failure rate */
1121     minfail = adj_mag_fail[player_ptr->stat_index[spell.use_stat]];
1122
1123     /* Minimum failure rate */
1124     if (chance < minfail)
1125         chance = minfail;
1126
1127     auto player_stun = player_ptr->effects()->stun();
1128     chance += player_stun->get_magic_chance_penalty();
1129     if (chance > 95) {
1130         chance = 95;
1131     }
1132
1133     /* Failed spell */
1134     if (randint0(100) < chance) {
1135         if (flush_failure)
1136             flush();
1137         msg_print(_("ものまねに失敗した!", "You failed to concentrate hard enough!"));
1138         sound(SOUND_FAIL);
1139     } else {
1140         sound(SOUND_ZAP);
1141         cast = use_mane(player_ptr, mane_data->mane_list[n].spell);
1142         if (!cast)
1143             return false;
1144     }
1145
1146     mane_data->mane_list.erase(std::next(mane_data->mane_list.begin(), n));
1147
1148     PlayerEnergy(player_ptr).set_player_turn_energy(100);
1149
1150     player_ptr->redraw |= (PR_IMITATION);
1151     player_ptr->window_flags |= (PW_PLAYER);
1152     player_ptr->window_flags |= (PW_SPELL);
1153
1154     return true;
1155 }