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/effect-processor.h"
13 #include "mind/drs-types.h"
14 #include "monster-race/monster-race.h"
15 #include "monster-race/race-ability-flags.h"
16 #include "monster-race/race-flags1.h"
17 #include "monster-race/race-flags3.h"
18 #include "monster-race/race-indice-types.h"
19 #include "monster/monster-describer.h"
20 #include "monster/monster-description-types.h"
21 #include "monster/monster-info.h"
22 #include "monster/monster-status-setter.h"
23 #include "monster/monster-status.h"
24 #include "monster/monster-update.h"
25 #include "mspell/mspell-checker.h"
26 #include "mspell/mspell-damage-calculator.h"
27 #include "mspell/mspell-util.h"
28 #include "mspell/mspell.h"
29 #include "player/player-personality-types.h"
30 #include "player/player-status-flags.h"
31 #include "effect/attribute-types.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 "view/display-messages.h"
40 mspell_cast_msg_bad_status_to_player::mspell_cast_msg_bad_status_to_player(concptr blind, concptr not_blind, concptr resist, concptr saved_throw)
42 , not_blind(not_blind)
44 , saved_throw(saved_throw)
47 mspell_cast_msg_bad_status_to_monster::mspell_cast_msg_bad_status_to_monster(concptr default_msg, concptr resist, concptr saved_throw, concptr success)
48 : default_msg(default_msg)
50 , saved_throw(saved_throw)
55 * @brief 状態異常呪文のメッセージ処理関数。 /
56 * @param player_ptr プレイヤーへの参照ポインタ
57 * @param m_idx 呪文を唱えるモンスターID
58 * @param msgs メッセージの構造体
59 * @param resist 耐性の有無を判別するフラグ
60 * @param saved_throw 抵抗に成功したか判別するフラグ
62 void spell_badstatus_message_to_player(player_type *player_ptr, MONSTER_IDX m_idx, const mspell_cast_msg_bad_status_to_player &msgs, bool resist,
65 GAME_TEXT m_name[MAX_NLEN];
66 monster_name(player_ptr, m_idx, m_name);
68 disturb(player_ptr, true, true);
69 if (player_ptr->blind)
70 msg_format(msgs.blind, m_name);
72 msg_format(msgs.not_blind, m_name);
75 msg_print(msgs.resist);
76 } else if (saved_throw) {
77 msg_print(msgs.saved_throw);
84 * @brief 状態異常呪文のメッセージ処理関数(対モンスター)。 /
85 * @param player_ptr プレーヤーへの参照ポインタ
86 * @param m_idx 呪文を唱えるモンスターID
87 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
88 * @param msgs メッセージの構造体
89 * @param resist 耐性の有無を判別するフラグ
90 * @param saved_throw 抵抗に成功したか判別するフラグ
92 void spell_badstatus_message_to_mons(player_type *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, const mspell_cast_msg_bad_status_to_monster &msgs, bool resist,
95 floor_type *floor_ptr = player_ptr->current_floor_ptr;
96 bool see_either = see_monster(player_ptr, m_idx) || see_monster(player_ptr, t_idx);
97 bool see_t = see_monster(player_ptr, t_idx);
98 bool known = monster_near_player(floor_ptr, m_idx, t_idx);
99 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
100 monster_name(player_ptr, m_idx, m_name);
101 monster_name(player_ptr, t_idx, t_name);
105 msg_format(msgs.default_msg, m_name, t_name);
107 floor_ptr->monster_noise = true;
113 msg_format(msgs.resist, t_name);
114 } else if (saved_throw) {
116 msg_format(msgs.saved_throw, t_name);
119 msg_format(msgs.success, t_name);
122 set_monster_csleep(player_ptr, t_idx, 0);
126 * @brief RF5_DRAIN_MANAの処理。魔力吸収。 /
127 * @param player_ptr プレイヤーへの参照ポインタ
130 * @param m_idx 呪文を唱えるモンスターID
131 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
132 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
136 MonsterSpellResult spell_RF5_DRAIN_MANA(player_type *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
138 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
139 monster_name(player_ptr, m_idx, m_name);
140 monster_name(player_ptr, t_idx, t_name);
142 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
143 disturb(player_ptr, true, true);
144 } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
146 msg_format(_("%^sは精神エネルギーを%sから吸いとった。", "%^s draws psychic energy from %s."), m_name, t_name);
149 const auto dam = monspell_damage(player_ptr, RF_ABILITY::DRAIN_MANA, m_idx, DAM_ROLL);
150 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::DRAIN_MANA, dam, 0, false, TARGET_TYPE);
151 if (TARGET_TYPE == MONSTER_TO_PLAYER)
152 update_smart_learn(player_ptr, m_idx, DRS_MANA);
154 auto res = MonsterSpellResult::make_valid();
155 res.learnable = proj_res.affected_player;
161 * @brief RF5_MIND_BLASTの処理。精神攻撃。 /
162 * @param player_ptr プレイヤーへの参照ポインタ
165 * @param m_idx 呪文を唱えるモンスターID
166 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
167 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
171 MonsterSpellResult spell_RF5_MIND_BLAST(player_type *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
173 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
174 bool seen = (!player_ptr->blind && m_ptr->ml);
175 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
176 monster_name(player_ptr, m_idx, m_name);
177 monster_name(player_ptr, t_idx, t_name);
179 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
180 disturb(player_ptr, true, true);
182 msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
184 msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
185 } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
186 msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
189 const auto dam = monspell_damage(player_ptr, RF_ABILITY::MIND_BLAST, m_idx, DAM_ROLL);
190 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::MIND_BLAST, dam, 0, false, TARGET_TYPE);
192 auto res = MonsterSpellResult::make_valid(dam);
193 res.learnable = proj_res.affected_player;
199 * @brief RF5_BRAIN_SMASHの処理。脳攻撃。 /
200 * @param player_ptr プレイヤーへの参照ポインタ
203 * @param m_idx 呪文を唱えるモンスターID
204 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
205 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
209 MonsterSpellResult spell_RF5_BRAIN_SMASH(player_type *player_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
211 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
212 bool seen = (!player_ptr->blind && m_ptr->ml);
213 GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
214 monster_name(player_ptr, m_idx, m_name);
215 monster_name(player_ptr, t_idx, t_name);
217 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
218 disturb(player_ptr, true, true);
220 msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
222 msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
223 } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(player_ptr, m_idx)) {
224 msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
227 const auto dam = monspell_damage(player_ptr, RF_ABILITY::BRAIN_SMASH, m_idx, DAM_ROLL);
228 const auto proj_res = breath(player_ptr, y, x, m_idx, AttributeType::BRAIN_SMASH, dam, 0, false, TARGET_TYPE);
230 auto res = MonsterSpellResult::make_valid(dam);
231 res.learnable = proj_res.affected_player;
237 * @brief RF5_SCAREの処理。恐怖。 /
238 * @param m_idx 呪文を唱えるモンスターID
239 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
240 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
244 MonsterSpellResult spell_RF5_SCARE(MONSTER_IDX m_idx, player_type *player_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
246 auto res = MonsterSpellResult::make_valid();
247 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
249 floor_type *floor_ptr = player_ptr->current_floor_ptr;
250 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
251 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
252 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
253 bool resist, saving_throw;
255 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
256 resist = (has_resist_fear(player_ptr) != 0);
257 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
259 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやくと、恐ろしげな音が聞こえた。", "%^s mumbles, and you hear scary noises."),
260 _("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion."), _("しかし恐怖に侵されなかった。", "You refuse to be frightened."),
261 _("しかし恐怖に侵されなかった。", "You refuse to be frightened."));
263 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
265 if (!resist && !saving_throw) {
266 (void)BadStatusSetter(player_ptr).mod_afraidness(randint0(4) + 4);
269 update_smart_learn(player_ptr, m_idx, DRS_FEAR);
273 if (TARGET_TYPE != MONSTER_TO_MONSTER)
276 resist = ((tr_ptr->flags3 & RF3_NO_FEAR) != 0);
277 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
279 mspell_cast_msg_bad_status_to_monster msg(_("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion in front of %s."),
280 _("%^sは恐怖を感じない。", "%^s refuses to be frightened."), _("%^sは恐怖を感じない。", "%^s refuses to be frightened."),
281 _("%^sは恐怖して逃げ出した!", "%^s flees in terror!"));
283 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
285 if (!resist && !saving_throw) {
286 set_monster_monfear(player_ptr, t_idx, monster_fear_remaining(t_ptr) + randint0(4) + 4);
293 * @brief RF5_BLINDの処理。盲目。 /
294 * @param m_idx 呪文を唱えるモンスターID
295 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
296 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
300 MonsterSpellResult spell_RF5_BLIND(MONSTER_IDX m_idx, player_type *player_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
302 auto res = MonsterSpellResult::make_valid();
303 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
305 floor_type *floor_ptr = player_ptr->current_floor_ptr;
306 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
307 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
308 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
309 bool resist, saving_throw;
311 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
312 resist = (has_resist_blind(player_ptr) != 0);
313 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
315 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
316 _("%^sが呪文を唱えてあなたの目をくらました!", "%^s casts a spell, burning your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
317 _("しかし効力を跳ね返した!", "You resist the effects!"));
319 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
321 if (!resist && !saving_throw) {
322 (void)BadStatusSetter(player_ptr).blindness(12 + randint0(4));
325 update_smart_learn(player_ptr, m_idx, DRS_BLIND);
329 if (TARGET_TYPE != MONSTER_TO_MONSTER)
333 GAME_TEXT t_name[MAX_NLEN];
334 monster_name(player_ptr, t_idx, t_name);
336 if (streq(t_name, "it")) {
337 msg_default = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %ss eyes.");
339 msg_default = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %s's eyes.");
342 resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
343 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
345 mspell_cast_msg_bad_status_to_monster msg(msg_default, _("%^sには効果がなかった。", "%^s is unaffected."),
346 _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは目が見えなくなった! ", "%^s is blinded!"));
348 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
350 if (!resist && !saving_throw) {
351 (void)set_monster_confused(player_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
358 * @brief RF5_CONFの処理。混乱。/
359 * @param m_idx 呪文を唱えるモンスターID
360 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
361 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
365 MonsterSpellResult spell_RF5_CONF(MONSTER_IDX m_idx, player_type *player_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
367 auto res = MonsterSpellResult::make_valid();
368 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
370 floor_type *floor_ptr = player_ptr->current_floor_ptr;
371 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
372 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
373 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
374 bool resist, saving_throw;
376 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
377 resist = (has_resist_conf(player_ptr) != 0);
378 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
380 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやくと、頭を悩ます音がした。", "%^s mumbles, and you hear puzzling noises."),
381 _("%^sが誘惑的な幻覚を作り出した。", "%^s creates a mesmerising illusion."),
382 _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."),
383 _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."));
385 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
387 if (!resist && !saving_throw) {
388 (void)BadStatusSetter(player_ptr).mod_confusion(randint0(4) + 4);
391 update_smart_learn(player_ptr, m_idx, DRS_CONF);
395 if (TARGET_TYPE != MONSTER_TO_MONSTER)
398 resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
399 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
401 mspell_cast_msg_bad_status_to_monster msg(_("%^sが%sの前に幻惑的な幻をつくり出した。", "%^s casts a mesmerizing illusion in front of %s."),
402 _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."), _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."),
403 _("%^sは混乱したようだ。", "%^s seems confused."));
405 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
407 if (!resist && !saving_throw) {
408 (void)set_monster_confused(player_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
415 * @brief RF5_HOLDの処理。麻痺。 /
416 * @param m_idx 呪文を唱えるモンスターID
417 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
418 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
422 MonsterSpellResult spell_RF5_HOLD(MONSTER_IDX m_idx, player_type *player_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
424 auto res = MonsterSpellResult::make_valid();
425 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
427 floor_type *floor_ptr = player_ptr->current_floor_ptr;
428 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
429 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
430 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
431 bool resist, saving_throw;
433 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
434 resist = (player_ptr->free_act != 0);
435 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
437 mspell_cast_msg_bad_status_to_player msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
438 _("%^sがあなたの目をじっと見つめた!", "%^s stares deep into your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
439 _("しかし効力を跳ね返した!", "You resist the effects!"));
441 spell_badstatus_message_to_player(player_ptr, m_idx, msg, (bool)resist, saving_throw);
443 if (!resist && !saving_throw) {
444 (void)BadStatusSetter(player_ptr).mod_paralysis(randint0(4) + 4);
447 update_smart_learn(player_ptr, m_idx, DRS_FREE);
451 if (TARGET_TYPE != MONSTER_TO_MONSTER)
454 resist = ((tr_ptr->flags1 & RF1_UNIQUE) != 0 || (tr_ptr->flags3 & RF3_NO_STUN) != 0);
455 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
457 mspell_cast_msg_bad_status_to_monster msg(_("%^sは%sをじっと見つめた。", "%^s stares intently at %s."),
458 _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは麻痺した!", "%^s is paralyzed!"));
460 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, (bool)resist, saving_throw);
462 if (!resist && !saving_throw) {
463 (void)set_monster_stunned(player_ptr, t_idx, monster_stunned_remaining(t_ptr) + randint1(4) + 4);
470 * @brief RF6_HASTEの処理。加速。 /
471 * @param player_ptr プレイヤーへの参照ポインタ
472 * @param m_idx 呪文を唱えるモンスターID
473 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
474 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
478 MonsterSpellResult spell_RF6_HASTE(player_type *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
480 bool see_m = see_monster(player_ptr, m_idx);
481 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
482 GAME_TEXT m_name[MAX_NLEN];
483 monster_name(player_ptr, m_idx, m_name);
485 monster_desc(player_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
487 mspell_cast_msg msg(_("%^sが何かをつぶやいた。", "%^s mumbles."),
488 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
489 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
490 _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)));
492 monspell_message_base(player_ptr, m_idx, t_idx, msg, player_ptr->blind > 0, TARGET_TYPE);
494 if (set_monster_fast(player_ptr, m_idx, monster_fast_remaining(m_ptr) + 100)) {
495 if (TARGET_TYPE == MONSTER_TO_PLAYER || (TARGET_TYPE == MONSTER_TO_MONSTER && see_m))
496 msg_format(_("%^sの動きが速くなった。", "%^s starts moving faster."), m_name);
499 return MonsterSpellResult::make_valid();
503 * @brief RF5_SLOWの処理。減速。 /
504 * @param m_idx 呪文を唱えるモンスターID
505 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
506 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
510 MonsterSpellResult spell_RF5_SLOW(MONSTER_IDX m_idx, player_type *player_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
512 auto res = MonsterSpellResult::make_valid();
513 res.learnable = TARGET_TYPE == MONSTER_TO_PLAYER;
515 floor_type *floor_ptr = player_ptr->current_floor_ptr;
516 monster_type *t_ptr = &floor_ptr->m_list[t_idx];
517 monster_race *tr_ptr = &r_info[t_ptr->r_idx];
518 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
519 bool resist, saving_throw;
521 if (TARGET_TYPE == MONSTER_TO_PLAYER) {
522 resist = (has_resist_conf(player_ptr) != 0);
523 saving_throw = (randint0(100 + rlev / 2) < player_ptr->skill_sav);
525 mspell_cast_msg_bad_status_to_player msg(_("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"),
526 _("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"), _("しかし効果がなかった!", "You are unaffected!"),
527 _("しかし効力を跳ね返した!", "You resist the effects!"));
529 spell_badstatus_message_to_player(player_ptr, m_idx, msg, resist, saving_throw);
531 if (!resist && !saving_throw) {
532 (void)BadStatusSetter(player_ptr).mod_slowness(randint0(4) + 4, false);
535 update_smart_learn(player_ptr, m_idx, DRS_FREE);
539 if (TARGET_TYPE != MONSTER_TO_MONSTER)
543 GAME_TEXT t_name[MAX_NLEN];
544 monster_name(player_ptr, t_idx, t_name);
546 if (streq(t_name, "it")) {
547 msg_default = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %ss muscles.");
549 msg_default = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %s's muscles.");
552 resist = ((tr_ptr->flags1 & RF1_UNIQUE) != 0);
553 saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
555 mspell_cast_msg_bad_status_to_monster msg(msg_default, _("%^sには効果がなかった。", "%^s is unaffected."),
556 _("%^sには効果がなかった。", "%^s is unaffected."), _("%sの動きが遅くなった。", "%^s starts moving slower."));
558 spell_badstatus_message_to_mons(player_ptr, m_idx, t_idx, msg, resist, saving_throw);
560 if (!resist && !saving_throw) {
561 set_monster_slow(player_ptr, t_idx, monster_slow_remaining(t_ptr) + 50);
568 * @brief RF6_HEALの処理。治癒。 /
569 * @param player_ptr プレイヤーへの参照ポインタ
570 * @param m_idx 呪文を唱えるモンスターID
571 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
572 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
576 MonsterSpellResult spell_RF6_HEAL(player_type *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
578 const auto res = MonsterSpellResult::make_valid();
581 floor_type *floor_ptr = player_ptr->current_floor_ptr;
582 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
583 DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
584 bool seen = (!player_ptr->blind && m_ptr->ml);
585 GAME_TEXT m_name[MAX_NLEN];
586 monster_name(player_ptr, m_idx, m_name);
588 monster_desc(player_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
590 disturb(player_ptr, true, true);
592 msg.to_player_true = _("%^sが何かをつぶやいた。", "%^s mumbles.");
593 msg.to_mons_true = _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss));
594 msg.to_player_false = _("%^sが自分の傷に集中した。", format("%%^s concentrates on %s wounds.", m_poss));
595 msg.to_mons_false = _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss));
597 monspell_message_base(player_ptr, m_idx, t_idx, msg, player_ptr->blind > 0, TARGET_TYPE);
599 m_ptr->hp += (rlev * 6);
600 if (m_ptr->hp >= m_ptr->maxhp) {
602 m_ptr->hp = m_ptr->maxhp;
604 msg.to_player_true = _("%^sは完全に治ったようだ!", "%^s sounds completely healed!");
605 msg.to_mons_true = _("%^sは完全に治ったようだ!", "%^s sounds completely healed!");
606 msg.to_player_false = _("%^sは完全に治った!", "%^s looks completely healed!");
607 msg.to_mons_false = _("%^sは完全に治った!", "%^s looks completely healed!");
609 msg.to_player_true = _("%^sは体力を回復したようだ。", "%^s sounds healthier.");
610 msg.to_mons_true = _("%^sは体力を回復したようだ。", "%^s sounds healthier.");
611 msg.to_player_false = _("%^sは体力を回復したようだ。", "%^s looks healthier.");
612 msg.to_mons_false = _("%^sは体力を回復したようだ。", "%^s looks healthier.");
615 monspell_message_base(player_ptr, m_idx, t_idx, msg, !seen, TARGET_TYPE);
617 if (player_ptr->health_who == m_idx)
618 player_ptr->redraw |= (PR_HEALTH);
619 if (player_ptr->riding == m_idx)
620 player_ptr->redraw |= (PR_UHEALTH);
622 if (!monster_fear_remaining(m_ptr))
625 (void)set_monster_monfear(player_ptr, m_idx, 0);
627 if (see_monster(player_ptr, m_idx))
628 msg_format(_("%^sは勇気を取り戻した。", format("%%^s recovers %s courage.", m_poss)), m_name);
634 * @brief RF6_INVULNERの処理。無敵。 /
635 * @param player_ptr プレイヤーへの参照ポインタ
636 * @param m_idx 呪文を唱えるモンスターID
637 * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
638 * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
642 MonsterSpellResult spell_RF6_INVULNER(player_type *player_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
644 monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
645 bool seen = (!player_ptr->blind && m_ptr->ml);
646 mspell_cast_msg msg(_("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
647 _("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."), _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."),
648 _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."));
650 monspell_message_base(player_ptr, m_idx, t_idx, msg, !seen, TARGET_TYPE);
653 MONRACE_IDX r_idx = m_ptr->r_idx;
654 GAME_TEXT m_name[MAX_NLEN];
655 monster_desc(player_ptr, m_name, m_ptr, MD_NONE);
659 msg_format(_("%sはスターを取った!", "%^s got a star!"), m_name);
662 msg_print(_("『読める』………動きの『軌跡』が読める……", "'Read'......... I can read the 'trajectory' of movement..."));
665 msg_format(_("%sの身体がまばゆく輝き始めた!", "The body of %^s began to shine dazzlingly!"), m_name);
670 if (!monster_invulner_remaining(m_ptr))
671 (void)set_monster_invulner(player_ptr, m_idx, randint1(4) + 4, false);
673 return MonsterSpellResult::make_valid();
677 * @brief RF6_FORGETの処理。記憶消去。 /
678 * @param player_ptr プレイヤーへの参照ポインタ
679 * @param m_idx 呪文を唱えるモンスターID
683 MonsterSpellResult spell_RF6_FORGET(player_type *player_ptr, MONSTER_IDX m_idx)
685 DEPTH rlev = monster_level_idx(player_ptr->current_floor_ptr, m_idx);
686 GAME_TEXT m_name[MAX_NLEN];
687 monster_name(player_ptr, m_idx, m_name);
689 disturb(player_ptr, true, true);
691 msg_format(_("%^sがあなたの記憶を消去しようとしている。", "%^s tries to blank your mind."), m_name);
693 if (randint0(100 + rlev / 2) < player_ptr->skill_sav) {
694 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
695 } else if (lose_all_info(player_ptr)) {
696 msg_print(_("記憶が薄れてしまった。", "Your memories fade away."));
699 auto res = MonsterSpellResult::make_valid();
700 res.learnable = true;