OSDN Git Service

[Refactor] enum spells-typeをenum class AttributeTypeに置換
[hengbandforosx/hengbandosx.git] / src / mspell / mspell-breath.cpp
1 #include "mspell/mspell-breath.h"
2 #include "core/disturbance.h"
3 #include "effect/effect-processor.h"
4 #include "main/sound-definitions-table.h"
5 #include "main/sound-of-music.h"
6 #include "mind/drs-types.h"
7 #include "monster-race/race-ability-flags.h"
8 #include "monster-race/race-indice-types.h"
9 #include "monster/monster-info.h"
10 #include "monster/monster-update.h"
11 #include "mspell/mspell-checker.h"
12 #include "mspell/mspell-damage-calculator.h"
13 #include "mspell/mspell-util.h"
14 #include "mspell/mspell.h"
15 #include "effect/attribute-types.h"
16 #include "system/floor-type-definition.h"
17 #include "system/monster-type-definition.h"
18 #include "system/player-type-definition.h"
19 #include "view/display-messages.h"
20
21 /*!
22  * @brief ブレスを吐くときにモンスター固有のセリフを表示する
23  * @param r_idx モンスター種族番号
24  * @param GF_TYPE 魔法効果
25  * @return 表示したらTRUE、しなかったらFALSE
26  */
27 static bool spell_RF4_BREATH_special_message(MONSTER_IDX r_idx, AttributeType GF_TYPE, concptr m_name)
28 {
29     if (r_idx == MON_JAIAN && GF_TYPE == AttributeType::SOUND) {
30         msg_format(_("%^s「ボォエ~~~~~~」", "%^s sings, 'Booooeeeeee'"), m_name);
31         return true;
32     }
33     if (r_idx == MON_BOTEI && GF_TYPE == AttributeType::SHARDS) {
34         msg_format(_("%^s「ボ帝ビルカッター!!!」", "%^s shouts, 'Boty-Build cutter!!!'"), m_name);
35         return true;
36     }
37     if (r_idx == MON_RAOU && GF_TYPE == AttributeType::FORCE) {
38         if (one_in_(2))
39             msg_format(_("%^s「北斗剛掌波!!」", "%^s says, 'Hokuto Goh-Sho-Ha!!'"), m_name);
40         else
41             msg_format(_("%^s「受けてみい!!天将奔烈!!!」", "%^s says, 'Tensho-Honretsu!!'"), m_name);
42         return true;
43     }
44     return false;
45 }
46
47 /*!
48  * @brief RF4_BR_*の処理。各種ブレス。 /
49  * @param player_ptr プレイヤーへの参照ポインタ
50  * @param GF_TYPE ブレスの属性
51  * @param y 対象の地点のy座標
52  * @param x 対象の地点のx座標
53  * @param m_idx 呪文を唱えるモンスターID
54  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
55  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
56  *
57  * プレイヤーに当たったらラーニング可。
58  */
59 MonsterSpellResult spell_RF4_BREATH(player_type *player_ptr, AttributeType GF_TYPE, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
60 {
61     HIT_POINT dam, drs_type = 0;
62     concptr type_s;
63     bool smart_learn_aux = true;
64     floor_type *floor_ptr = player_ptr->current_floor_ptr;
65     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
66     bool known = monster_near_player(floor_ptr, m_idx, t_idx);
67     bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
68     bool mon_to_mon = (TARGET_TYPE == MONSTER_TO_MONSTER);
69     bool mon_to_player = (TARGET_TYPE == MONSTER_TO_PLAYER);
70     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
71     monster_name(player_ptr, m_idx, m_name);
72     monster_name(player_ptr, t_idx, t_name);
73
74     switch (GF_TYPE) {
75     case AttributeType::ACID:
76         dam = monspell_damage(player_ptr, RF_ABILITY::BR_ACID, m_idx, DAM_ROLL);
77         type_s = _("酸", "acid");
78         drs_type = DRS_ACID;
79         break;
80     case AttributeType::ELEC:
81         dam = monspell_damage(player_ptr, RF_ABILITY::BR_ELEC, m_idx, DAM_ROLL);
82         type_s = _("稲妻", "lightning");
83         drs_type = DRS_ELEC;
84         break;
85     case AttributeType::FIRE:
86         dam = monspell_damage(player_ptr, RF_ABILITY::BR_FIRE, m_idx, DAM_ROLL);
87         type_s = _("火炎", "fire");
88         drs_type = DRS_FIRE;
89         break;
90     case AttributeType::COLD:
91         dam = monspell_damage(player_ptr, RF_ABILITY::BR_COLD, m_idx, DAM_ROLL);
92         type_s = _("冷気", "frost");
93         drs_type = DRS_COLD;
94         break;
95     case AttributeType::POIS:
96         dam = monspell_damage(player_ptr, RF_ABILITY::BR_POIS, m_idx, DAM_ROLL);
97         type_s = _("ガス", "gas");
98         drs_type = DRS_POIS;
99         break;
100     case AttributeType::NETHER:
101         dam = monspell_damage(player_ptr, RF_ABILITY::BR_NETH, m_idx, DAM_ROLL);
102         type_s = _("地獄", "nether");
103         drs_type = DRS_NETH;
104         break;
105     case AttributeType::LITE:
106         dam = monspell_damage(player_ptr, RF_ABILITY::BR_LITE, m_idx, DAM_ROLL);
107         type_s = _("閃光", "light");
108         drs_type = DRS_LITE;
109         break;
110     case AttributeType::DARK:
111         dam = monspell_damage(player_ptr, RF_ABILITY::BR_DARK, m_idx, DAM_ROLL);
112         type_s = _("暗黒", "darkness");
113         drs_type = DRS_DARK;
114         break;
115     case AttributeType::CONFUSION:
116         dam = monspell_damage(player_ptr, RF_ABILITY::BR_CONF, m_idx, DAM_ROLL);
117         type_s = _("混乱", "confusion");
118         drs_type = DRS_CONF;
119         break;
120     case AttributeType::SOUND:
121         dam = monspell_damage(player_ptr, RF_ABILITY::BR_SOUN, m_idx, DAM_ROLL);
122         type_s = _("轟音", "sound");
123         drs_type = DRS_SOUND;
124         break;
125     case AttributeType::CHAOS:
126         dam = monspell_damage(player_ptr, RF_ABILITY::BR_CHAO, m_idx, DAM_ROLL);
127         type_s = _("カオス", "chaos");
128         drs_type = DRS_CHAOS;
129         break;
130     case AttributeType::DISENCHANT:
131         dam = monspell_damage(player_ptr, RF_ABILITY::BR_DISE, m_idx, DAM_ROLL);
132         type_s = _("劣化", "disenchantment");
133         drs_type = DRS_DISEN;
134         break;
135     case AttributeType::NEXUS:
136         dam = monspell_damage(player_ptr, RF_ABILITY::BR_NEXU, m_idx, DAM_ROLL);
137         type_s = _("因果混乱", "nexus");
138         drs_type = DRS_NEXUS;
139         break;
140     case AttributeType::TIME:
141         dam = monspell_damage(player_ptr, RF_ABILITY::BR_TIME, m_idx, DAM_ROLL);
142         type_s = _("時間逆転", "time");
143         smart_learn_aux = false;
144         break;
145     case AttributeType::INERTIAL:
146         dam = monspell_damage(player_ptr, RF_ABILITY::BR_INER, m_idx, DAM_ROLL);
147         type_s = _("遅鈍", "inertia");
148         smart_learn_aux = false;
149         break;
150     case AttributeType::GRAVITY:
151         dam = monspell_damage(player_ptr, RF_ABILITY::BR_GRAV, m_idx, DAM_ROLL);
152         type_s = _("重力", "gravity");
153         smart_learn_aux = false;
154         break;
155     case AttributeType::SHARDS:
156         dam = monspell_damage(player_ptr, RF_ABILITY::BR_SHAR, m_idx, DAM_ROLL);
157         type_s = _("破片", "shards");
158         drs_type = DRS_SHARD;
159         break;
160     case AttributeType::PLASMA:
161         dam = monspell_damage(player_ptr, RF_ABILITY::BR_PLAS, m_idx, DAM_ROLL);
162         type_s = _("プラズマ", "plasma");
163         smart_learn_aux = false;
164         break;
165     case AttributeType::FORCE:
166         dam = monspell_damage(player_ptr, RF_ABILITY::BR_FORC, m_idx, DAM_ROLL);
167         type_s = _("フォース", "force");
168         smart_learn_aux = false;
169         break;
170     case AttributeType::MANA:
171         dam = monspell_damage(player_ptr, RF_ABILITY::BR_MANA, m_idx, DAM_ROLL);
172         type_s = _("魔力", "mana");
173         smart_learn_aux = false;
174         break;
175     case AttributeType::NUKE:
176         dam = monspell_damage(player_ptr, RF_ABILITY::BR_NUKE, m_idx, DAM_ROLL);
177         type_s = _("放射性廃棄物", "toxic waste");
178         drs_type = DRS_POIS;
179         break;
180     case AttributeType::DISINTEGRATE:
181         dam = monspell_damage(player_ptr, RF_ABILITY::BR_DISI, m_idx, DAM_ROLL);
182         type_s = _("分解", "disintegration");
183         smart_learn_aux = false;
184         break;
185     default:
186         /* Do not reach here */
187         dam = 0;
188         type_s = _("不明", "Unknown");
189         smart_learn_aux = false;
190         break;
191     }
192
193     if (mon_to_player || (mon_to_mon && known && see_either))
194         disturb(player_ptr, true, true);
195
196     if (!spell_RF4_BREATH_special_message(m_ptr->r_idx, GF_TYPE, m_name)) {
197         if (player_ptr->blind) {
198             if (mon_to_player || (mon_to_mon && known && see_either))
199                 msg_format(_("%^sが何かのブレスを吐いた。", "%^s breathes."), m_name);
200         } else {
201             if (mon_to_player) {
202                 msg_format(_("%^sが%^sのブレスを吐いた。", "%^s breathes %^s."), m_name, type_s);
203             } else if (mon_to_mon && known && see_either) {
204                 _(msg_format("%^sが%^sに%^sのブレスを吐いた。", m_name, t_name, type_s), msg_format("%^s breathes %^s at %^s.", m_name, type_s, t_name));
205             }
206         }
207     }
208
209     if (mon_to_mon && known && !see_either)
210         floor_ptr->monster_noise = true;
211
212     if (known || see_either)
213         sound(SOUND_BREATH);
214
215     const auto proj_res = breath(player_ptr, y, x, m_idx, GF_TYPE, dam, 0, true, TARGET_TYPE);
216     if (smart_learn_aux && mon_to_player)
217         update_smart_learn(player_ptr, m_idx, drs_type);
218
219     auto res = MonsterSpellResult::make_valid(dam);
220     res.learnable = proj_res.affected_player;
221
222     return res;
223 }