2 * @brief プレイヤーのステータスを下げるか、モンスター自身のステータスを上げるスペル類の処理
5 * @todo やや過密気味。モンスター自身のステータスとプレイヤーのステータスで分けてもいいかもしれない.
8 #include "mspell/mspell-status.h"
9 #include "blue-magic/blue-magic-checker.h"
10 #include "core/disturbance.h"
11 #include "core/player-redraw-types.h"
12 #include "effect/attribute-types.h"
13 #include "effect/effect-processor.h"
14 #include "mind/drs-types.h"
15 #include "monster-race/monster-race.h"
16 #include "monster-race/race-ability-flags.h"
17 #include "monster-race/race-flags1.h"
18 #include "monster-race/race-flags3.h"
19 #include "monster-race/race-indice-types.h"
20 #include "monster/monster-describer.h"
21 #include "monster/monster-description-types.h"
22 #include "monster/monster-info.h"
23 #include "monster/monster-status-setter.h"
24 #include "monster/monster-status.h"
25 #include "monster/monster-update.h"
26 #include "mspell/mspell-checker.h"
27 #include "mspell/mspell-damage-calculator.h"
28 #include "mspell/mspell-result.h"
29 #include "mspell/mspell-util.h"
30 #include "player/player-personality-types.h"
31 #include "player/player-status-flags.h"
32 #include "status/bad-status-setter.h"
33 #include "status/base-status.h"
34 #include "system/floor-type-definition.h"
35 #include "system/monster-race-definition.h"
36 #include "system/monster-type-definition.h"
37 #include "system/player-type-definition.h"
38 #include "timed-effect/player-blindness.h"
39 #include "timed-effect/timed-effects.h"
40 #include "view/display-messages.h"
42 mspell_cast_msg_bad_status_to_player::mspell_cast_msg_bad_status_to_player(concptr blind, concptr not_blind, concptr resist, concptr saved_throw)
44 , not_blind(not_blind)
46 , saved_throw(saved_throw)
50 mspell_cast_msg_bad_status_to_monster::mspell_cast_msg_bad_status_to_monster(concptr default_msg, concptr resist, concptr saved_throw, concptr success)
51 : default_msg(default_msg)
53 , saved_throw(saved_throw)
59 * @brief 状態異常呪文のメッセージ処理関数。 /
60 * @param player_ptr プレイヤーへの参照ポインタ
61 * @param m_idx 呪文を唱えるモンスターID
62 * @param msgs メッセージの構造体
63 * @param resist 耐性の有無を判別するフラグ
64 * @param saved_throw 抵抗に成功したか判別するフラグ
66 void spell_badstatus_message_to_player(PlayerType *player_ptr, MONSTER_IDX m_idx, const mspell_cast_msg_bad_status_to_player &msgs, bool resist,
69 GAME_TEXT m_name[MAX_NLEN];
70 monster_name(player_ptr, m_idx, m_name);
72 disturb(player_ptr, true, true);
73 if (player_ptr->effects()->blindness()->is_blind()) {
74 msg_format(msgs.blind, m_name);
76 msg_format(msgs.not_blind, m_name);
80 msg_print(msgs.resist);
81 } else if (saved_throw) {
82 msg_print(msgs.saved_throw);
89 * @brief 状態異常呪文のメッセージ処理関数(対モンスター)。 /
90 * @param player_ptr プレーヤーへの参照ポインタ
91 * @param m_idx 呪文を唱えるモンスターID
92 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
93 * @param msgs メッセージの構造体
94 * @param resist 耐性の有無を判別するフラグ
95 * @param saved_throw 抵抗に成功したか判別するフラグ
97 void spell_badstatus_message_to_mons(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, const mspell_cast_msg_bad_status_to_monster &msgs, bool resist,
100 auto *floor_ptr = player_ptr->current_floor_ptr;
101 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
102 bool see_t = see_monster(player_ptr, t_idx);
103 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
104 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
105 monster_name(player_ptr, m_idx, m_name);
106 monster_name(player_ptr, t_idx, t_name);
110 msg_format(msgs.default_msg, m_name, t_name);
112 floor_ptr->monster_noise = true;
118 msg_format(msgs.resist, t_name);
120 } else if (saved_throw) {
122 msg_format(msgs.saved_throw, t_name);
126 msg_format(msgs.success, t_name);
130 set_monster_csleep(player_ptr, t_idx, 0);
134 * @brief RF5_DRAIN_MANAの処理。魔力吸収。 /
135 * @param player_ptr プレイヤーへの参照ポインタ
138 * @param m_idx 呪文を唱えるモンスターID
139 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
140 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
144 MonsterSpellResult spell_RF5_DRAIN_MANA(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
146 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
147 monster_name(player_ptr, m_idx, m_name);
148 monster_name(player_ptr, t_idx, t_name);
150 if (target_type == MONSTER_TO_PLAYER) {
151 disturb(player_ptr, true, true);
152 } else if (target_type == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
154 msg_format(_("%^sは精神エネルギーを%sから吸いとった。", "%^s draws psychic energy from %s."), m_name, t_name);
157 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::DRAIN_MANA, m_idx, DAM_ROLL);
158 const auto proj_res = pointed(player_ptr, y, x, m_idx, AttributeType::DRAIN_MANA, dam, target_type);
159 if (target_type == MONSTER_TO_PLAYER) {
160 update_smart_learn(player_ptr, m_idx, DRS_MANA);
163 auto res = MonsterSpellResult::make_valid();
164 res.learnable = proj_res.affected_player;
170 * @brief RF5_MIND_BLASTの処理。精神攻撃。 /
171 * @param player_ptr プレイヤーへの参照ポインタ
174 * @param m_idx 呪文を唱えるモンスターID
175 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
176 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
180 MonsterSpellResult spell_RF5_MIND_BLAST(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
182 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
183 bool seen = (!player_ptr->effects()->blindness()->is_blind() && m_ptr->ml);
184 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
185 monster_name(player_ptr, m_idx, m_name);
186 monster_name(player_ptr, t_idx, t_name);
188 if (target_type == MONSTER_TO_PLAYER) {
189 disturb(player_ptr, true, true);
191 msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
193 msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
195 } else if (target_type == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
196 msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
199 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::MIND_BLAST, m_idx, DAM_ROLL);
200 const auto proj_res = pointed(player_ptr, y, x, m_idx, AttributeType::MIND_BLAST, dam, target_type);
202 auto res = MonsterSpellResult::make_valid(dam);
203 res.learnable = proj_res.affected_player;
209 * @brief RF5_BRAIN_SMASHの処理。脳攻撃。 /
210 * @param player_ptr プレイヤーへの参照ポインタ
213 * @param m_idx 呪文を唱えるモンスターID
214 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
215 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
219 MonsterSpellResult spell_RF5_BRAIN_SMASH(PlayerType *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
221 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
222 bool seen = (!player_ptr->effects()->blindness()->is_blind() && m_ptr->ml);
223 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
224 monster_name(player_ptr, m_idx, m_name);
225 monster_name(player_ptr, t_idx, t_name);
227 if (target_type == MONSTER_TO_PLAYER) {
228 disturb(player_ptr, true, true);
230 msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
232 msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
234 } else if (target_type == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
235 msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
238 const auto dam = monspell_damage(player_ptr, MonsterAbilityType::BRAIN_SMASH, m_idx, DAM_ROLL);
239 const auto proj_res = pointed(player_ptr, y, x, m_idx, AttributeType::BRAIN_SMASH, dam, target_type);
241 auto res = MonsterSpellResult::make_valid(dam);
242 res.learnable = proj_res.affected_player;
248 * @brief RF5_SCAREの処理。恐怖。 /
249 * @param m_idx 呪文を唱えるモンスターID
250 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
251 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
255 MonsterSpellResult spell_RF5_SCARE(MONSTER_IDX m_idx, PlayerType *player_ptr, MONSTER_IDX t_idx, int target_type)
257 auto res = MonsterSpellResult::make_valid();
258 res.learnable = target_type == MONSTER_TO_PLAYER;
260 auto *floor_ptr = player_ptr->current_floor_ptr;
261 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
262 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
263 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
264 bool resist, saving_throw;
266 if (target_type == MONSTER_TO_PLAYER) {
267 resist = (has_resist_fear(player_ptr) != 0);
268 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
270 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやくと、恐ろしげな音が聞こえた。", "%^s mumbles, and you hear scary noises."),
271 _("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion."), _("しかし恐怖に侵されなかった。", "You refuse to be frightened."),
272 _("しかし恐怖に侵されなかった。", "You refuse to be frightened."));
274 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
276 if (!resist && !saving_throw) {
277 (void)BadStatusSetter(player_ptr).mod_fear(randint0(4) + 4);
280 update_smart_learn(player_ptr, m_idx, DRS_FEAR);
284 if (target_type != MONSTER_TO_MONSTER) {
288 resist = ((tr_ptr->flags3 & RF3_NO_FEAR) != 0);
289 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
291 mspell_cast_msg_bad_status_to_monster msg(_("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion in front of %s."),
292 _("%^sは恐怖を感じない。", "%^s refuses to be frightened."), _("%^sは恐怖を感じない。", "%^s refuses to be frightened."),
293 _("%^sは恐怖して逃げ出した!", "%^s flees in terror!"));
295 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
297 if (!resist && !saving_throw) {
298 set_monster_monfear(player_ptr, t_idx, monster_fear_remaining(t_ptr) + randint0(4) + 4);
305 * @brief RF5_BLINDの処理。盲目。 /
306 * @param m_idx 呪文を唱えるモンスターID
307 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
308 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
312 MonsterSpellResult spell_RF5_BLIND(MONSTER_IDX m_idx, PlayerType *player_ptr, MONSTER_IDX t_idx, int target_type)
314 auto res = MonsterSpellResult::make_valid();
315 res.learnable = target_type == MONSTER_TO_PLAYER;
317 auto *floor_ptr = player_ptr->current_floor_ptr;
318 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
319 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
320 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
321 bool resist, saving_throw;
323 if (target_type == MONSTER_TO_PLAYER) {
324 resist = (has_resist_blind(player_ptr) != 0);
325 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
327 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
328 _("%^sが呪文を唱えてあなたの目をくらました!", "%^s casts a spell, burning your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
329 _("しかし効力を跳ね返した!", "You resist the effects!"));
331 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
333 if (!resist && !saving_throw) {
334 (void)BadStatusSetter(player_ptr).blindness(12 + randint0(4));
337 update_smart_learn(player_ptr, m_idx, DRS_BLIND);
341 if (target_type != MONSTER_TO_MONSTER) {
346 GAME_TEXT t_name[MAX_NLEN];
347 monster_name(player_ptr, t_idx, t_name);
349 if (streq(t_name, "it")) {
350 msg_default = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %ss eyes.");
352 msg_default = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %s's eyes.");
355 resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
356 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
358 mspell_cast_msg_bad_status_to_monster msg(msg_default, _("%^sには効果がなかった。", "%^s is unaffected."),
359 _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは目が見えなくなった! ", "%^s is blinded!"));
361 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
363 if (!resist && !saving_throw) {
364 (void)set_monster_confused(player_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
371 * @brief RF5_CONFの処理。混乱。/
372 * @param m_idx 呪文を唱えるモンスターID
373 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
374 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
378 MonsterSpellResult spell_RF5_CONF(MONSTER_IDX m_idx, PlayerType *player_ptr, MONSTER_IDX t_idx, int target_type)
380 auto res = MonsterSpellResult::make_valid();
381 res.learnable = target_type == MONSTER_TO_PLAYER;
383 auto *floor_ptr = player_ptr->current_floor_ptr;
384 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
385 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
386 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
387 bool resist, saving_throw;
389 if (target_type == MONSTER_TO_PLAYER) {
390 resist = (has_resist_conf(player_ptr) != 0);
391 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
393 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやくと、頭を悩ます音がした。", "%^s mumbles, and you hear puzzling noises."),
394 _("%^sが誘惑的な幻覚を作り出した。", "%^s creates a mesmerising illusion."),
395 _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."),
396 _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."));
398 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
400 if (!resist && !saving_throw) {
401 (void)BadStatusSetter(player_ptr).mod_confusion(randint0(4) + 4);
404 update_smart_learn(player_ptr, m_idx, DRS_CONF);
408 if (target_type != MONSTER_TO_MONSTER) {
412 resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
413 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
415 mspell_cast_msg_bad_status_to_monster msg(_("%^sが%sの前に幻惑的な幻をつくり出した。", "%^s casts a mesmerizing illusion in front of %s."),
416 _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."), _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."),
417 _("%^sは混乱したようだ。", "%^s seems confused."));
419 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
421 if (!resist && !saving_throw) {
422 (void)set_monster_confused(player_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
429 * @brief RF5_HOLDの処理。麻痺。 /
430 * @param m_idx 呪文を唱えるモンスターID
431 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
432 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
436 MonsterSpellResult spell_RF5_HOLD(MONSTER_IDX m_idx, PlayerType *player_ptr, MONSTER_IDX t_idx, int target_type)
438 auto res = MonsterSpellResult::make_valid();
439 res.learnable = target_type == MONSTER_TO_PLAYER;
441 auto *floor_ptr = player_ptr->current_floor_ptr;
442 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
443 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
444 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
445 bool resist, saving_throw;
447 if (target_type == MONSTER_TO_PLAYER) {
448 resist = (player_ptr->free_act != 0);
449 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
451 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
452 _("%^sがあなたの目をじっと見つめた!", "%^s stares deep into your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
453 _("しかし効力を跳ね返した!", "You resist the effects!"));
455 spell_badstatus_message_to_player(player_ptr, m_idx, msg, (bool)resist, saving_throw);
457 if (!resist && !saving_throw) {
458 (void)BadStatusSetter(player_ptr).mod_paralysis(randint0(4) + 4);
461 update_smart_learn(player_ptr, m_idx, DRS_FREE);
465 if (target_type != MONSTER_TO_MONSTER) {
469 resist = (tr_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (tr_ptr->flags3 & RF3_NO_STUN) != 0);
470 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
472 mspell_cast_msg_bad_status_to_monster msg(_("%^sは%sをじっと見つめた。", "%^s stares intently at %s."),
473 _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは麻痺した!", "%^s is paralyzed!"));
475 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, (bool)resist, saving_throw);
477 if (!resist && !saving_throw) {
478 (void)set_monster_stunned(player_ptr, t_idx, monster_stunned_remaining(t_ptr) + randint1(4) + 4);
485 * @brief RF6_HASTEの処理。加速。 /
486 * @param player_ptr プレイヤーへの参照ポインタ
487 * @param m_idx 呪文を唱えるモンスターID
488 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
489 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
493 MonsterSpellResult spell_RF6_HASTE(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
495 bool see_m = see_monster(player_ptr, m_idx);
496 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
497 GAME_TEXT m_name[MAX_NLEN];
498 monster_name(player_ptr, m_idx, m_name);
500 monster_desc(player_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
502 mspell_cast_msg msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
503 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
504 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
505 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)));
507 monspell_message_base(player_ptr, m_idx, t_idx, msg, player_ptr->effects()->blindness()->is_blind(), target_type);
509 if (set_monster_fast(player_ptr, m_idx, monster_fast_remaining(m_ptr) + 100)) {
510 if (target_type == MONSTER_TO_PLAYER || (target_type == MONSTER_TO_MONSTER && see_m)) {
511 msg_format(_("%^sの動きが速くなった。", "%^s starts moving faster."), m_name);
515 return MonsterSpellResult::make_valid();
519 * @brief RF5_SLOWの処理。減速。 /
520 * @param m_idx 呪文を唱えるモンスターID
521 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
522 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
526 MonsterSpellResult spell_RF5_SLOW(MONSTER_IDX m_idx, PlayerType *player_ptr, MONSTER_IDX t_idx, int target_type)
528 auto res = MonsterSpellResult::make_valid();
529 res.learnable = target_type == MONSTER_TO_PLAYER;
531 auto *floor_ptr = player_ptr->current_floor_ptr;
532 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
533 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
534 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
535 bool resist, saving_throw;
537 if (target_type == MONSTER_TO_PLAYER) {
538 resist = (has_resist_conf(player_ptr) != 0);
539 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
541 mspell_cast_msg_bad_status_to_player msg(_("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"),
542 _("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"), _("しかし効果がなかった!", "You are unaffected!"),
543 _("しかし効力を跳ね返した!", "You resist the effects!"));
545 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
547 if (!resist && !saving_throw) {
548 (void)BadStatusSetter(player_ptr).mod_deceleration(randint0(4) + 4, false);
551 update_smart_learn(player_ptr, m_idx, DRS_FREE);
555 if (target_type != MONSTER_TO_MONSTER) {
560 GAME_TEXT t_name[MAX_NLEN];
561 monster_name(player_ptr, t_idx, t_name);
563 if (streq(t_name, "it")) {
564 msg_default = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %ss muscles.");
566 msg_default = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %s's muscles.");
569 resist = (tr_ptr->kind_flags.has(MonsterKindType::UNIQUE));
570 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
572 mspell_cast_msg_bad_status_to_monster msg(msg_default, _("%^sには効果がなかった。", "%^s is unaffected."),
573 _("%^sには効果がなかった。", "%^s is unaffected."), _("%sの動きが遅くなった。", "%^s starts moving slower."));
575 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
577 if (!resist && !saving_throw) {
578 set_monster_slow(player_ptr, t_idx, monster_slow_remaining(t_ptr) + 50);
585 * @brief RF6_HEALの処理。治癒。 /
586 * @param player_ptr プレイヤーへの参照ポインタ
587 * @param m_idx 呪文を唱えるモンスターID
588 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
589 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
593 MonsterSpellResult spell_RF6_HEAL(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
595 const auto res = MonsterSpellResult::make_valid();
598 auto *floor_ptr = player_ptr->current_floor_ptr;
599 auto *m_ptr = &floor_ptr->m_list[m_idx];
600 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
601 const auto is_blind = player_ptr->effects()->blindness()->is_blind();
602 const auto seen = (!is_blind && m_ptr->ml);
603 GAME_TEXT m_name[MAX_NLEN];
604 monster_name(player_ptr, m_idx, m_name);
606 monster_desc(player_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
608 msg.to_player_true = _("%^sが何かをつぶやいた。", "%^s mumbles.");
609 msg.to_mons_true = _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss));
610 msg.to_player_false = _("%^sが自分の傷に集中した。", format("%%^s concentrates on %s wounds.", m_poss));
611 msg.to_mons_false = _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss));
613 monspell_message_base(player_ptr, m_idx, t_idx, msg, is_blind, target_type);
615 m_ptr->hp += (rlev * 6);
616 if (m_ptr->hp >= m_ptr->maxhp) {
618 m_ptr->hp = m_ptr->maxhp;
620 msg.to_player_true = _("%^sは完全に治ったようだ!", "%^s sounds completely healed!");
621 msg.to_mons_true = _("%^sは完全に治ったようだ!", "%^s sounds completely healed!");
622 msg.to_player_false = _("%^sは完全に治った!", "%^s looks completely healed!");
623 msg.to_mons_false = _("%^sは完全に治った!", "%^s looks completely healed!");
625 msg.to_player_true = _("%^sは体力を回復したようだ。", "%^s sounds healthier.");
626 msg.to_mons_true = _("%^sは体力を回復したようだ。", "%^s sounds healthier.");
627 msg.to_player_false = _("%^sは体力を回復したようだ。", "%^s looks healthier.");
628 msg.to_mons_false = _("%^sは体力を回復したようだ。", "%^s looks healthier.");
631 monspell_message_base(player_ptr, m_idx, t_idx, msg, !seen, target_type);
633 if (player_ptr->health_who == m_idx) {
634 player_ptr->redraw |= (PR_HEALTH);
636 if (player_ptr->riding == m_idx) {
637 player_ptr->redraw |= (PR_UHEALTH);
640 if (!monster_fear_remaining(m_ptr)) {
644 (void)set_monster_monfear(player_ptr, m_idx, 0);
646 if (see_monster(player_ptr, m_idx)) {
647 msg_format(_("%^sは勇気を取り戻した。", format("%%^s recovers %s courage.", m_poss)), m_name);
654 * @brief RF6_INVULNERの処理。無敵。 /
655 * @param player_ptr プレイヤーへの参照ポインタ
656 * @param m_idx 呪文を唱えるモンスターID
657 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
658 * @param target_type プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
662 MonsterSpellResult spell_RF6_INVULNER(PlayerType *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int target_type)
664 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
665 bool seen = (!player_ptr->effects()->blindness()->is_blind() && m_ptr->ml);
666 mspell_cast_msg msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
667 _("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."), _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."),
668 _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."));
670 monspell_message_base(player_ptr, m_idx, t_idx, msg, !seen, target_type);
673 MonsterRaceId r_idx = m_ptr->r_idx;
674 GAME_TEXT m_name[MAX_NLEN];
675 monster_desc(player_ptr, m_name, m_ptr, MD_NONE);
677 case MonsterRaceId::MARIO:
678 case MonsterRaceId::LUIGI:
679 msg_format(_("%sはスターを取った!", "%^s got a star!"), m_name);
681 case MonsterRaceId::DIAVOLO:
682 msg_print(_("『読める』………動きの『軌跡』が読める……", "'Read'......... I can read the 'trajectory' of movement..."));
685 msg_format(_("%sの身体がまばゆく輝き始めた!", "The body of %^s began to shine dazzlingly!"), m_name);
690 if (!monster_invulner_remaining(m_ptr)) {
691 (void)set_monster_invulner(player_ptr, m_idx, randint1(4) + 4, false);
694 return MonsterSpellResult::make_valid();
698 * @brief RF6_FORGETの処理。記憶消去。 /
699 * @param player_ptr プレイヤーへの参照ポインタ
700 * @param m_idx 呪文を唱えるモンスターID
704 MonsterSpellResult spell_RF6_FORGET(PlayerType *player_ptr, MONSTER_IDX m_idx)
706 DEPTH rlev = monster_level_idx(player_ptr->current_floor_ptr, m_idx);
707 GAME_TEXT m_name[MAX_NLEN];
708 monster_name(player_ptr, m_idx, m_name);
710 disturb(player_ptr, true, true);
712 msg_format(_("%^sがあなたの記憶を消去しようとしている。", "%^s tries to blank your mind."), m_name);
714 if (randint0(100 + rlev / 2) < player_ptr->skill_sav) {
715 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
716 } else if (lose_all_info(player_ptr)) {
717 msg_print(_("記憶が薄れてしまった。", "Your memories fade away."));
720 auto res = MonsterSpellResult::make_valid();
721 res.learnable = true;