1 #include "mspell/mspell-ball.h"
2 #include "effect/attribute-types.h"
3 #include "effect/effect-processor.h"
4 #include "main/sound-of-music.h"
5 #include "mind/drs-types.h"
6 #include "monster-race/race-ability-flags.h"
7 #include "monster-race/race-indice-types.h"
8 #include "monster/monster-info.h"
9 #include "monster/monster-status.h"
10 #include "monster/monster-update.h"
11 #include "mspell/mspell-checker.h"
12 #include "mspell/mspell-damage-calculator.h"
13 #include "mspell/mspell-result.h"
14 #include "mspell/mspell-util.h"
15 #include "system/floor-type-definition.h"
16 #include "system/monster-type-definition.h"
17 #include "system/player-type-definition.h"
18 #include "view/display-messages.h"
21 * @brief RF4_BA_NUKEの処理。放射能球。 /
22 * @param player_ptr プレイヤーへの参照ポインタ
25 * @param m_idx 呪文を唱えるモンスターID
26 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
27 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
31 MonsterSpellResult spell_RF4_BA_NUKE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
33 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが放射能球を放った。", "%^s casts a ball of radiation."),
34 _("%^sが%sに放射能球を放った。", "%^s casts a ball of radiation at %s."));
36 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
38 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_NUKE, m_idx, DAM_ROLL);
39 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::NUKE, dam, 2, false, target_type);
40 if (target_type == MONSTER_TO_PLAYER) {
41 update_smart_learn(player_ptr, m_idx, DRS_POIS);
44 auto res = MonsterSpellResult::make_valid(dam);
45 res.learnable = proj_res.affected_player;
51 * @brief RF4_BA_CHAOの処理。純ログルス。 /
52 * @param player_ptr プレイヤーへの参照ポインタ
55 * @param m_idx 呪文を唱えるモンスターID
56 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
57 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
61 MonsterSpellResult spell_RF4_BA_CHAO(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
63 mspell_cast_msg_blind msg(_("%^sが恐ろしげにつぶやいた。", "%^s mumbles frighteningly."),
64 _("%^sが純ログルスを放った。", "%^s invokes a raw Logrus."), _("%^sが%sに純ログルスを放った。", "%^s invokes raw Logrus upon %s."));
66 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
68 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_CHAO, m_idx, DAM_ROLL);
69 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::CHAOS, dam, 4, false, target_type);
70 if (target_type == MONSTER_TO_PLAYER) {
71 update_smart_learn(player_ptr, m_idx, DRS_CHAOS);
74 auto res = MonsterSpellResult::make_valid(dam);
75 res.learnable = proj_res.affected_player;
81 * @brief RF5_BA_ACIDの処理。アシッド・ボール。 /
82 * @param player_ptr プレイヤーへの参照ポインタ
85 * @param m_idx 呪文を唱えるモンスターID
86 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
87 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
91 MonsterSpellResult spell_RF5_BA_ACID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
93 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
94 _("%^sがアシッド・ボールの呪文を唱えた。", "%^s casts an acid ball."),
95 _("%^sが%sに向かってアシッド・ボールの呪文を唱えた。", "%^s casts an acid ball at %s."));
97 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
99 const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
100 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ACID, m_idx, DAM_ROLL);
101 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ACID, dam, rad, false, target_type);
102 if (target_type == MONSTER_TO_PLAYER) {
103 update_smart_learn(player_ptr, m_idx, DRS_ACID);
106 auto res = MonsterSpellResult::make_valid(dam);
107 res.learnable = proj_res.affected_player;
113 * @brief RF5_BA_ELECの処理。サンダー・ボール。 /
114 * @param player_ptr プレイヤーへの参照ポインタ
117 * @param m_idx 呪文を唱えるモンスターID
118 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
119 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
123 MonsterSpellResult spell_RF5_BA_ELEC(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
125 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
126 _("%^sがサンダー・ボールの呪文を唱えた。", "%^s casts a lightning ball."),
127 _("%^sが%sに向かってサンダー・ボールの呪文を唱えた。", "%^s casts a lightning ball at %s."));
129 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
131 const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
132 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ELEC, m_idx, DAM_ROLL);
133 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ELEC, dam, rad, false, target_type);
134 if (target_type == MONSTER_TO_PLAYER) {
135 update_smart_learn(player_ptr, m_idx, DRS_ELEC);
138 auto res = MonsterSpellResult::make_valid(dam);
139 res.learnable = proj_res.affected_player;
145 * @brief RF5_BA_FIREの処理。ファイア・ボール。 /
146 * @param player_ptr プレイヤーへの参照ポインタ
149 * @param m_idx 呪文を唱えるモンスターID
150 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
151 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
155 MonsterSpellResult spell_RF5_BA_FIRE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
157 mspell_cast_msg_blind msg;
158 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
160 if (m_ptr->r_idx == MON_ROLENTO) {
161 msg.blind = _("%sが何かを投げた。", "%^s throws something.");
162 msg.to_player = _("%sは手榴弾を投げた。", "%^s throws a hand grenade.");
163 msg.to_mons = _("%^sが%^sに向かって手榴弾を投げた。", "%^s throws a hand grenade.");
165 msg.blind = _("%^sが何かをつぶやいた。", "%^s mumbles.");
166 msg.to_player = _("%^sがファイア・ボールの呪文を唱えた。", "%^s casts a fire ball.");
167 msg.to_mons = _("%^sが%sに向かってファイア・ボールの呪文を唱えた。", "%^s casts a fire ball at %s.");
170 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
172 const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
173 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_FIRE, m_idx, DAM_ROLL);
174 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::FIRE, dam, rad, false, target_type);
175 if (target_type == MONSTER_TO_PLAYER) {
176 update_smart_learn(player_ptr, m_idx, DRS_FIRE);
179 auto res = MonsterSpellResult::make_valid(dam);
180 res.learnable = proj_res.affected_player;
186 * @brief RF5_BA_COLDの処理。アイス・ボール。 /
187 * @param player_ptr プレイヤーへの参照ポインタ
190 * @param m_idx 呪文を唱えるモンスターID
191 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
192 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
196 MonsterSpellResult spell_RF5_BA_COLD(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
198 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
199 _("%^sがアイス・ボールの呪文を唱えた。", "%^s casts a frost ball."),
200 _("%^sが%sに向かってアイス・ボールの呪文を唱えた。", "%^s casts a frost ball at %s."));
202 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
204 const auto rad = monster_is_powerful(player_ptr->current_floor_ptr, m_idx) ? 4 : 2;
205 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_COLD, m_idx, DAM_ROLL);
206 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::COLD, dam, rad, false, target_type);
207 if (target_type == MONSTER_TO_PLAYER) {
208 update_smart_learn(player_ptr, m_idx, DRS_COLD);
211 auto res = MonsterSpellResult::make_valid(dam);
212 res.learnable = proj_res.affected_player;
218 * @brief RF5_BA_POISの処理。悪臭雲。 /
219 * @param player_ptr プレイヤーへの参照ポインタ
222 * @param m_idx 呪文を唱えるモンスターID
223 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
224 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
228 MonsterSpellResult spell_RF5_BA_POIS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
230 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが悪臭雲の呪文を唱えた。", "%^s casts a stinking cloud."),
231 _("%^sが%sに向かって悪臭雲の呪文を唱えた。", "%^s casts a stinking cloud at %s."));
233 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
235 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_POIS, m_idx, DAM_ROLL);
236 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::POIS, dam, 2, false, target_type);
237 if (target_type == MONSTER_TO_PLAYER) {
238 update_smart_learn(player_ptr, m_idx, DRS_POIS);
241 auto res = MonsterSpellResult::make_valid(dam);
242 res.learnable = proj_res.affected_player;
248 * @brief RF5_BA_NETHの処理。地獄球。 /
249 * @param player_ptr プレイヤーへの参照ポインタ
252 * @param m_idx 呪文を唱えるモンスターID
253 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
254 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
258 MonsterSpellResult spell_RF5_BA_NETH(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
260 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが地獄球の呪文を唱えた。", "%^s casts a nether ball."),
261 _("%^sが%sに向かって地獄球の呪文を唱えた。", "%^s casts a nether ball at %s."));
263 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
265 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_NETH, m_idx, DAM_ROLL);
266 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::NETHER, dam, 2, false, target_type);
267 if (target_type == MONSTER_TO_PLAYER) {
268 update_smart_learn(player_ptr, m_idx, DRS_NETH);
271 auto res = MonsterSpellResult::make_valid(dam);
272 res.learnable = proj_res.affected_player;
278 * @brief RF5_BA_WATEの処理。ウォーター・ボール。 /
279 * @param player_ptr プレイヤーへの参照ポインタ
282 * @param m_idx 呪文を唱えるモンスターID
283 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
284 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
288 MonsterSpellResult spell_RF5_BA_WATE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
290 bool known = monster_near_player(player_ptr->current_floor_ptr, m_idx, t_idx);
291 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
292 bool mon_to_mon = (target_type == MONSTER_TO_MONSTER);
293 bool mon_to_player = (target_type == MONSTER_TO_PLAYER);
294 GAME_TEXT t_name[MAX_NLEN];
295 monster_name(player_ptr, t_idx, t_name);
297 mspell_cast_msg_blind msg(_("%^sが何かをつぶやいた。", "%^s mumbles."), _("%^sが流れるような身振りをした。", "%^s gestures fluidly."),
298 _("%^sが%sに対して流れるような身振りをした。", "%^s gestures fluidly at %s."));
300 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
303 msg_format(_("あなたは渦巻きに飲み込まれた。", "You are engulfed in a whirlpool."));
304 } else if (mon_to_mon && known && see_either && !player_ptr->blind) {
305 msg_format(_("%^sは渦巻に飲み込まれた。", "%^s is engulfed in a whirlpool."), t_name);
308 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_WATE, m_idx, DAM_ROLL);
309 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::WATER, dam, 4, false, target_type);
311 auto res = MonsterSpellResult::make_valid(dam);
312 res.learnable = proj_res.affected_player;
318 * @brief RF5_BA_MANAの処理。魔力の嵐。 /
319 * @param player_ptr プレイヤーへの参照ポインタ
322 * @param m_idx 呪文を唱えるモンスターID
323 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
324 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
328 MonsterSpellResult spell_RF5_BA_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
330 mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
331 _("%^sが魔力の嵐の呪文を念じた。", "%^s invokes a mana storm."), _("%^sが%sに対して魔力の嵐の呪文を念じた。", "%^s invokes a mana storm upon %s."));
333 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
335 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_MANA, m_idx, DAM_ROLL);
336 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::MANA, dam, 4, false, target_type);
338 auto res = MonsterSpellResult::make_valid(dam);
339 res.learnable = proj_res.affected_player;
345 * @brief RF5_BA_DARKの処理。暗黒の嵐。 /
346 * @param player_ptr プレイヤーへの参照ポインタ
349 * @param m_idx 呪文を唱えるモンスターID
350 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
351 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
355 MonsterSpellResult spell_RF5_BA_DARK(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
357 mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
358 _("%^sが暗黒の嵐の呪文を念じた。", "%^s invokes a darkness storm."),
359 _("%^sが%sに対して暗黒の嵐の呪文を念じた。", "%^s invokes a darkness storm upon %s."));
361 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
363 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_DARK, m_idx, DAM_ROLL);
364 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::DARK, dam, 4, false, target_type);
365 if (target_type == MONSTER_TO_PLAYER) {
366 update_smart_learn(player_ptr, m_idx, DRS_DARK);
369 auto res = MonsterSpellResult::make_valid(dam);
370 res.learnable = proj_res.affected_player;
376 * @brief RF5_BA_LITEの処理。スターバースト。 /
377 * @param player_ptr プレイヤーへの参照ポインタ
380 * @param m_idx 呪文を唱えるモンスターID
381 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
382 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
386 MonsterSpellResult spell_RF5_BA_LITE(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
388 mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
389 _("%^sがスターバーストの呪文を念じた。", "%^s invokes a starburst."),
390 _("%^sが%sに対してスターバーストの呪文を念じた。", "%^s invokes a starburst upon %s."));
392 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
394 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_LITE, m_idx, DAM_ROLL);
395 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::LITE, dam, 4, false, target_type);
396 if (target_type == MONSTER_TO_PLAYER) {
397 update_smart_learn(player_ptr, m_idx, DRS_LITE);
400 auto res = MonsterSpellResult::make_valid(dam);
401 res.learnable = proj_res.affected_player;
407 * @brief RF5_BA_VOIDの処理。虚無の嵐。 /
408 * @param player_ptr プレイヤーへの参照ポインタ
411 * @param m_idx 呪文を唱えるモンスターID
412 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
413 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
417 MonsterSpellResult spell_RF5_BA_VOID(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
419 mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
420 _("%^sが虚無の嵐の呪文を念じた。", "%^s invokes a void storm."),
421 _("%^sが%sに対して虚無の嵐の呪文を念じた。", "%^s invokes a void storm upon %s."));
423 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
425 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_VOID, m_idx, DAM_ROLL);
426 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::VOID_MAGIC, dam, 4, false, target_type);
428 auto res = MonsterSpellResult::make_valid(dam);
429 res.learnable = proj_res.affected_player;
435 * @brief RF5_BA_ABYSSの処理。アビス・ボール。 /
436 * @param player_ptr プレイヤーへの参照ポインタ
439 * @param m_idx 呪文を唱えるモンスターID
440 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
441 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
445 MonsterSpellResult spell_RF5_BA_ABYSS(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
447 mspell_cast_msg_blind msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
448 _("%^sが深淵の嵐の呪文を念じた。", "%^s invokes a abyss storm."),
449 _("%^sが%sに対して深淵の嵐の呪文を念じた。", "%^s invokes a void abyss upon %s."));
451 monspell_message(player_ptr, m_idx, t_idx, msg, target_type);
453 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BA_ABYSS, m_idx, DAM_ROLL);
454 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::ABYSS, dam, 4, false, target_type);
455 if (target_type == MONSTER_TO_PLAYER) {
456 update_smart_learn(player_ptr, m_idx, DRS_DARK);
459 auto res = MonsterSpellResult::make_valid(dam);
460 res.learnable = proj_res.affected_player;