OSDN Git Service

203c367db7369a047dd963683318e9e6ac5f8f58
[hengbandforosx/hengbandosx.git] / src / mind / mind-blue-mage.cpp
1 #include "mind/mind-blue-mage.h"
2 #include "action/action-limited.h"
3 #include "avatar/avatar.h"
4 #include "blue-magic/blue-magic-caster.h"
5 #include "blue-magic/learnt-power-getter.h"
6 #include "core/asking-player.h"
7 #include "core/player-redraw-types.h"
8 #include "core/window-redrawer.h"
9 #include "game-option/disturbance-options.h"
10 #include "game-option/input-options.h"
11 #include "main/sound-definitions-table.h"
12 #include "main/sound-of-music.h"
13 #include "monster-race/race-ability-mask.h"
14 #include "mspell/monster-power-table.h"
15 #include "player-status/player-energy.h"
16 #include "player/player-status-table.h"
17 #include "realm/realm-types.h"
18 #include "spell/spell-info.h"
19 #include "status/bad-status-setter.h"
20 #include "status/base-status.h"
21 #include "system/player-type-definition.h"
22 #include "system/redrawing-flags-updater.h"
23 #include "term/screen-processor.h"
24 #include "timed-effect/player-stun.h"
25 #include "timed-effect/timed-effects.h"
26 #include "view/display-messages.h"
27
28 /*!
29  * @brief 青魔法コマンドのメインルーチン /
30  * do_cmd_cast calls this function if the player's class is 'Blue-Mage'.
31  * @return 処理を実行したらTRUE、キャンセルした場合FALSEを返す。
32  */
33 bool do_cmd_cast_learned(PlayerType *player_ptr)
34 {
35     if (cmd_limit_confused(player_ptr)) {
36         return false;
37     }
38
39     auto selected_spell = get_learned_power(player_ptr);
40     if (!selected_spell.has_value()) {
41         return false;
42     }
43
44     const auto &spell = monster_powers.at(selected_spell.value());
45     const auto need_mana = mod_need_mana(player_ptr, spell.smana, 0, REALM_NONE);
46     if (need_mana > player_ptr->csp) {
47         msg_print(_("MPが足りません。", "You do not have enough mana to use this power."));
48         if (!over_exert) {
49             return false;
50         }
51
52         if (!get_check(_("それでも挑戦しますか? ", "Attempt it anyway? "))) {
53             return false;
54         }
55     }
56
57     const auto chance = calculate_blue_magic_failure_probability(player_ptr, spell, need_mana);
58
59     if (randint0(100) < chance) {
60         if (flush_failure) {
61             flush();
62         }
63
64         msg_print(_("魔法をうまく唱えられなかった。", "You failed to concentrate hard enough!"));
65         sound(SOUND_FAIL);
66         if (RF_ABILITY_SUMMON_MASK.has(selected_spell.value())) {
67             cast_learned_spell(player_ptr, selected_spell.value(), false);
68         }
69     } else {
70         sound(SOUND_ZAP);
71         if (!cast_learned_spell(player_ptr, selected_spell.value(), true)) {
72             return false;
73         }
74     }
75
76     if (need_mana <= player_ptr->csp) {
77         player_ptr->csp -= need_mana;
78     } else {
79         int oops = need_mana;
80         player_ptr->csp = 0;
81         player_ptr->csp_frac = 0;
82         msg_print(_("精神を集中しすぎて気を失ってしまった!", "You faint from the effort!"));
83         (void)BadStatusSetter(player_ptr).mod_paralysis(randint1(5 * oops + 1));
84         chg_virtue(player_ptr, Virtue::KNOWLEDGE, -10);
85         if (randint0(100) < 50) {
86             bool perm = (randint0(100) < 25);
87             msg_print(_("体を悪くしてしまった!", "You have damaged your health!"));
88             (void)dec_stat(player_ptr, A_CON, 15 + randint1(10), perm);
89         }
90     }
91
92     PlayerEnergy(player_ptr).set_player_turn_energy(100);
93     auto &rfu = RedrawingFlagsUpdater::get_instance();
94     rfu.set_flag(MainWindowRedrawingFlag::MP);
95     player_ptr->window_flags |= PW_PLAYER | PW_SPELL;
96     return true;
97 }