OSDN Git Service

Reworded English description of the sniper's SP_PIERCE ability.
[hengband/hengband.git] / src / mspell / mspell-status.c
1 /*!
2  * todo やや過密気味。モンスター自身のステータスとプレーヤーのステータスで分けてもいいかもしれない.
3  * @brief プレーヤーのステータスを下げるか、モンスター自身のステータスを上げるスペル類の処理
4  * @date 2020/05/16
5  * @author Hourier
6  */
7
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 "mind/drs-types.h"
13 #include "monster-race/monster-race.h"
14 #include "monster-race/race-indice-types.h"
15 #include "monster-race/race-flags1.h"
16 #include "monster-race/race-flags3.h"
17 #include "monster/monster-describer.h"
18 #include "monster/monster-description-types.h"
19 #include "monster/monster-info.h"
20 #include "monster/monster-status-setter.h"
21 #include "monster/monster-status.h"
22 #include "monster/monster-update.h"
23 #include "mspell/mspell-checker.h"
24 #include "mspell/mspell-damage-calculator.h"
25 #include "mspell/mspell-util.h"
26 #include "player/player-personalities-types.h"
27 #include "player/player-status-flags.h"
28 #include "spell/spell-types.h"
29 #include "status/bad-status-setter.h"
30 #include "status/base-status.h"
31 #include "system/floor-type-definition.h"
32 #include "view/display-messages.h"
33
34 /*!
35  * @brief 状態異常呪文のメッセージ処理関数。 /
36  * @param target_ptr プレーヤーへの参照ポインタ
37  * @param m_idx 呪文を唱えるモンスターID
38  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
39  * @param msg1 対プレイヤーなら盲目時メッセージ。対モンスターなら通常時メッセージ。
40  * @param msg2 対プレイヤーなら非盲目時メッセージ。対モンスターなら耐性有メッセージ。
41  * @param msg3 対プレイヤーなら耐性有メッセージ。対モンスターなら抵抗時メッセージ。
42  * @param msg4 対プレイヤーなら抵抗時メッセージ。対モンスターなら成功時メッセージ。
43  * @param resist 耐性の有無を判別するフラグ
44  * @param saving_throw 抵抗に成功したか判別するフラグ
45  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
46  */
47 void spell_badstatus_message(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, concptr msg1, concptr msg2, concptr msg3, concptr msg4, bool resist,
48     bool saving_throw, int TARGET_TYPE)
49 {
50     floor_type *floor_ptr = target_ptr->current_floor_ptr;
51     bool see_either = see_monster(target_ptr, m_idx) || see_monster(target_ptr, t_idx);
52     bool see_t = see_monster(target_ptr, t_idx);
53     bool known = monster_near_player(floor_ptr, m_idx, t_idx);
54     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
55     monster_name(target_ptr, m_idx, m_name);
56     monster_name(target_ptr, t_idx, t_name);
57
58     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
59         disturb(target_ptr, TRUE, TRUE);
60         if (target_ptr->blind)
61             msg_format(msg1, m_name);
62         else
63             msg_format(msg2, m_name);
64
65         if (resist) {
66             msg_print(msg3);
67         } else if (saving_throw) {
68             msg_print(msg4);
69         }
70
71         return;
72     }
73
74     if (TARGET_TYPE != MONSTER_TO_MONSTER)
75         return;
76
77     if (known) {
78         if (see_either) {
79             msg_format(msg1, m_name, t_name);
80         } else {
81             floor_ptr->monster_noise = TRUE;
82         }
83     }
84
85     if (resist) {
86         if (see_t)
87             msg_format(msg2, t_name);
88     } else if (saving_throw) {
89         if (see_t)
90             msg_format(msg3, t_name);
91     } else {
92         if (see_t)
93             msg_format(msg4, t_name);
94     }
95
96     set_monster_csleep(target_ptr, t_idx, 0);
97 }
98
99 /*!
100  * @brief RF5_DRAIN_MANAの処理。魔力吸収。 /
101  * @param target_ptr プレーヤーへの参照ポインタ
102  * @param y 対象の地点のy座標
103  * @param x 対象の地点のx座標
104  * @param m_idx 呪文を唱えるモンスターID
105  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
106  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
107  * @return ダメージ量を返す。
108  */
109 HIT_POINT spell_RF5_DRAIN_MANA(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
110 {
111     HIT_POINT dam;
112     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
113     monster_name(target_ptr, m_idx, m_name);
114     monster_name(target_ptr, t_idx, t_name);
115
116     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
117         disturb(target_ptr, TRUE, TRUE);
118     } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(target_ptr, m_idx)) {
119         /* Basic message */
120         msg_format(_("%^sは精神エネルギーを%sから吸いとった。", "%^s draws psychic energy from %s."), m_name, t_name);
121     }
122
123     dam = monspell_damage(target_ptr, (MS_DRAIN_MANA), m_idx, DAM_ROLL);
124     breath(target_ptr, y, x, m_idx, GF_DRAIN_MANA, dam, 0, FALSE, MS_DRAIN_MANA, TARGET_TYPE);
125     if (TARGET_TYPE == MONSTER_TO_PLAYER)
126         update_smart_learn(target_ptr, m_idx, DRS_MANA);
127
128     return dam;
129 }
130
131 /*!
132  * @brief RF5_MIND_BLASTの処理。精神攻撃。 /
133  * @param target_ptr プレーヤーへの参照ポインタ
134  * @param y 対象の地点のy座標
135  * @param x 対象の地点のx座標
136  * @param m_idx 呪文を唱えるモンスターID
137  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
138  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
139  * @return ダメージ量を返す。
140  */
141 HIT_POINT spell_RF5_MIND_BLAST(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
142 {
143     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
144     bool seen = (!target_ptr->blind && m_ptr->ml);
145     HIT_POINT dam;
146     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
147     monster_name(target_ptr, m_idx, m_name);
148     monster_name(target_ptr, t_idx, t_name);
149
150     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
151         disturb(target_ptr, TRUE, TRUE);
152         if (!seen)
153             msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
154         else
155             msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
156     } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(target_ptr, m_idx)) {
157         msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
158     }
159
160     dam = monspell_damage(target_ptr, (MS_MIND_BLAST), m_idx, DAM_ROLL);
161     breath(target_ptr, y, x, m_idx, GF_MIND_BLAST, dam, 0, FALSE, MS_MIND_BLAST, TARGET_TYPE);
162     return dam;
163 }
164
165 /*!
166  * @brief RF5_BRAIN_SMASHの処理。脳攻撃。 /
167  * @param target_ptr プレーヤーへの参照ポインタ
168  * @param y 対象の地点のy座標
169  * @param x 対象の地点のx座標
170  * @param m_idx 呪文を唱えるモンスターID
171  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
172  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
173  * @return ダメージ量を返す。
174  */
175 HIT_POINT spell_RF5_BRAIN_SMASH(player_type *target_ptr, POSITION y, POSITION x, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
176 {
177     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
178     bool seen = (!target_ptr->blind && m_ptr->ml);
179     HIT_POINT dam;
180     GAME_TEXT m_name[MAX_NLEN], t_name[MAX_NLEN];
181     monster_name(target_ptr, m_idx, m_name);
182     monster_name(target_ptr, t_idx, t_name);
183
184     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
185         disturb(target_ptr, TRUE, TRUE);
186         if (!seen)
187             msg_print(_("何かがあなたの精神に念を放っているようだ。", "You feel something focusing on your mind."));
188         else
189             msg_format(_("%^sがあなたの瞳をじっとにらんでいる。", "%^s gazes deep into your eyes."), m_name);
190     } else if (TARGET_TYPE == MONSTER_TO_MONSTER && see_monster(target_ptr, m_idx)) {
191         msg_format(_("%^sは%sをじっと睨んだ。", "%^s gazes intently at %s."), m_name, t_name);
192     }
193
194     dam = monspell_damage(target_ptr, (MS_BRAIN_SMASH), m_idx, DAM_ROLL);
195     breath(target_ptr, y, x, m_idx, GF_BRAIN_SMASH, dam, 0, FALSE, MS_BRAIN_SMASH, TARGET_TYPE);
196     return dam;
197 }
198
199 /*!
200  * @brief RF5_SCAREの処理。恐怖。 /
201  * @param m_idx 呪文を唱えるモンスターID
202  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
203  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
204  */
205 void spell_RF5_SCARE(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
206 {
207     floor_type *floor_ptr = target_ptr->current_floor_ptr;
208     monster_type *t_ptr = &floor_ptr->m_list[t_idx];
209     monster_race *tr_ptr = &r_info[t_ptr->r_idx];
210     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
211     bool resist, saving_throw;
212
213     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
214         resist = (has_resist_fear(target_ptr) != 0);
215         saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
216         spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやくと、恐ろしげな音が聞こえた。", "%^s mumbles, and you hear scary noises."),
217             _("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion."), _("しかし恐怖に侵されなかった。", "You refuse to be frightened."),
218             _("しかし恐怖に侵されなかった。", "You refuse to be frightened."), resist, saving_throw, TARGET_TYPE);
219
220         if (!resist && !saving_throw) {
221             (void)set_afraid(target_ptr, target_ptr->afraid + randint0(4) + 4);
222         }
223
224         learn_spell(target_ptr, MS_SCARE);
225         update_smart_learn(target_ptr, m_idx, DRS_FEAR);
226         return;
227     }
228
229     if (TARGET_TYPE != MONSTER_TO_MONSTER)
230         return;
231
232     resist = ((tr_ptr->flags3 & RF3_NO_FEAR) != 0);
233     saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
234
235     spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが恐ろしげな幻覚を作り出した。", "%^s casts a fearful illusion in front of %s."),
236         _("%^sは恐怖を感じない。", "%^s refuses to be frightened."), _("%^sは恐怖を感じない。", "%^s refuses to be frightened."),
237         _("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), resist, saving_throw, TARGET_TYPE);
238
239     if (!resist && !saving_throw) {
240         set_monster_monfear(target_ptr, t_idx, monster_fear_remaining(t_ptr) + randint0(4) + 4);
241     }
242 }
243
244 /*!
245  * @brief RF5_BLINDの処理。盲目。 /
246  * @param m_idx 呪文を唱えるモンスターID
247  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
248  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
249  */
250 void spell_RF5_BLIND(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
251 {
252     floor_type *floor_ptr = target_ptr->current_floor_ptr;
253     monster_type *t_ptr = &floor_ptr->m_list[t_idx];
254     monster_race *tr_ptr = &r_info[t_ptr->r_idx];
255     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
256     bool resist, saving_throw;
257
258     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
259         resist = (has_resist_blind(target_ptr) != 0);
260         saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
261         spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
262             _("%^sが呪文を唱えてあなたの目をくらました!", "%^s casts a spell, burning your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
263             _("しかし効力を跳ね返した!", "You resist the effects!"), resist, saving_throw, TARGET_TYPE);
264
265         if (!resist && !saving_throw) {
266             (void)set_blind(target_ptr, 12 + randint0(4));
267         }
268
269         learn_spell(target_ptr, MS_BLIND);
270         update_smart_learn(target_ptr, m_idx, DRS_BLIND);
271         return;
272     }
273
274     if (TARGET_TYPE != MONSTER_TO_MONSTER)
275         return;
276
277     concptr msg1;
278     GAME_TEXT t_name[MAX_NLEN];
279     monster_name(target_ptr, t_idx, t_name);
280
281     if (streq(t_name, "it")) {
282         msg1 = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %ss eyes.");
283     } else {
284         msg1 = _("%sは呪文を唱えて%sの目を焼き付かせた。", "%^s casts a spell, burning %s's eyes.");
285     }
286
287     resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
288     saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
289
290     spell_badstatus_message(target_ptr, m_idx, t_idx, msg1, _("%^sには効果がなかった。", "%^s is unaffected."),
291         _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは目が見えなくなった! ", "%^s is blinded!"), resist, saving_throw, TARGET_TYPE);
292
293     if (!resist && !saving_throw) {
294         (void)set_monster_confused(target_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
295     }
296 }
297
298 /*!
299  * @brief RF5_CONFの処理。混乱。/
300  * @param m_idx 呪文を唱えるモンスターID
301  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
302  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
303  */
304 void spell_RF5_CONF(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
305 {
306     floor_type *floor_ptr = target_ptr->current_floor_ptr;
307     monster_type *t_ptr = &floor_ptr->m_list[t_idx];
308     monster_race *tr_ptr = &r_info[t_ptr->r_idx];
309     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
310     bool resist, saving_throw;
311
312     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
313         resist = (has_resist_conf(target_ptr) != 0);
314         saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
315         spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやくと、頭を悩ます音がした。", "%^s mumbles, and you hear puzzling noises."),
316             _("%^sが誘惑的な幻覚を作り出した。", "%^s creates a mesmerising illusion."),
317             _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."),
318             _("しかし幻覚にはだまされなかった。", "You disbelieve the feeble spell."), resist, saving_throw, TARGET_TYPE);
319
320         if (!resist && !saving_throw) {
321             (void)set_confused(target_ptr, target_ptr->confused + randint0(4) + 4);
322         }
323
324         learn_spell(target_ptr, MS_CONF);
325         update_smart_learn(target_ptr, m_idx, DRS_CONF);
326         return;
327     }
328
329     if (TARGET_TYPE != MONSTER_TO_MONSTER)
330         return;
331
332     resist = ((tr_ptr->flags3 & RF3_NO_CONF) != 0);
333     saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
334
335     spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが%sの前に幻惑的な幻をつくり出した。", "%^s casts a mesmerizing illusion in front of %s."),
336         _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."), _("%^sは惑わされなかった。", "%^s disbelieves the feeble spell."),
337         _("%^sは混乱したようだ。", "%^s seems confused."), resist, saving_throw, TARGET_TYPE);
338
339     if (!resist && !saving_throw) {
340         (void)set_monster_confused(target_ptr, t_idx, monster_confused_remaining(t_ptr) + 12 + randint0(4));
341     }
342 }
343
344 /*!
345  * @brief RF5_HOLDの処理。麻痺。 /
346  * @param m_idx 呪文を唱えるモンスターID
347  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
348  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
349  */
350 void spell_RF5_HOLD(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
351 {
352     floor_type *floor_ptr = target_ptr->current_floor_ptr;
353     monster_type *t_ptr = &floor_ptr->m_list[t_idx];
354     monster_race *tr_ptr = &r_info[t_ptr->r_idx];
355     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
356     bool resist, saving_throw;
357
358     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
359         resist = (target_ptr->free_act != 0);
360         saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
361         spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
362             _("%^sがあなたの目をじっと見つめた!", "%^s stares deep into your eyes!"), _("しかし効果がなかった!", "You are unaffected!"),
363             _("しかし効力を跳ね返した!", "You resist the effects!"), (bool)resist, saving_throw, TARGET_TYPE);
364
365         if (!resist && !saving_throw) {
366             (void)set_paralyzed(target_ptr, target_ptr->paralyzed + randint0(4) + 4);
367         }
368
369         learn_spell(target_ptr, MS_SLEEP);
370         update_smart_learn(target_ptr, m_idx, DRS_FREE);
371         return;
372     }
373
374     if (TARGET_TYPE != MONSTER_TO_MONSTER)
375         return;
376
377     resist = ((tr_ptr->flags1 & RF1_UNIQUE) != 0 || (tr_ptr->flags3 & RF3_NO_STUN) != 0);
378     saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
379
380     spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sは%sをじっと見つめた。", "%^s stares intently at %s."),
381         _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sには効果がなかった。", "%^s is unaffected."), _("%^sは麻痺した!", "%^s is paralyzed!"),
382         (bool)resist, saving_throw, TARGET_TYPE);
383
384     if (!resist && !saving_throw) {
385         (void)set_monster_stunned(target_ptr, t_idx, monster_stunned_remaining(t_ptr) + randint1(4) + 4);
386     }
387 }
388
389 /*!
390  * @brief RF6_HASTEの処理。加速。 /
391  * @param target_ptr プレーヤーへの参照ポインタ
392  * @param m_idx 呪文を唱えるモンスターID
393  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
394  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
395  */
396 void spell_RF6_HASTE(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
397 {
398     bool see_m = see_monster(target_ptr, m_idx);
399     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
400     GAME_TEXT m_name[MAX_NLEN];
401     monster_name(target_ptr, m_idx, m_name);
402     char m_poss[10];
403     monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
404
405     monspell_message_base(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
406         _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
407         _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)),
408         _("%^sが自分の体に念を送った。", format("%%^s concentrates on %s body.", m_poss)), target_ptr->blind > 0, TARGET_TYPE);
409
410     if (set_monster_fast(target_ptr, m_idx, monster_fast_remaining(m_ptr) + 100)) {
411         if (TARGET_TYPE == MONSTER_TO_PLAYER || (TARGET_TYPE == MONSTER_TO_MONSTER && see_m))
412             msg_format(_("%^sの動きが速くなった。", "%^s starts moving faster."), m_name);
413     }
414 }
415
416 /*!
417  * @brief RF5_SLOWの処理。減速。 /
418  * @param m_idx 呪文を唱えるモンスターID
419  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
420  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
421  */
422 void spell_RF5_SLOW(MONSTER_IDX m_idx, player_type *target_ptr, MONSTER_IDX t_idx, int TARGET_TYPE)
423 {
424     floor_type *floor_ptr = target_ptr->current_floor_ptr;
425     monster_type *t_ptr = &floor_ptr->m_list[t_idx];
426     monster_race *tr_ptr = &r_info[t_ptr->r_idx];
427     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
428     bool resist, saving_throw;
429
430     if (TARGET_TYPE == MONSTER_TO_PLAYER) {
431         resist = (has_resist_conf(target_ptr) != 0);
432         saving_throw = (randint0(100 + rlev / 2) < target_ptr->skill_sav);
433         spell_badstatus_message(target_ptr, m_idx, t_idx, _("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"),
434             _("%^sがあなたの筋力を吸い取ろうとした!", "%^s drains power from your muscles!"), _("しかし効果がなかった!", "You are unaffected!"),
435             _("しかし効力を跳ね返した!", "You resist the effects!"), resist, saving_throw, TARGET_TYPE);
436
437         if (!resist && !saving_throw) {
438             (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
439         }
440
441         learn_spell(target_ptr, MS_SLOW);
442         update_smart_learn(target_ptr, m_idx, DRS_FREE);
443         return;
444     }
445
446     if (TARGET_TYPE != MONSTER_TO_MONSTER)
447         return;
448
449     concptr msg1;
450     GAME_TEXT t_name[MAX_NLEN];
451     monster_name(target_ptr, t_idx, t_name);
452
453     if (streq(t_name, "it")) {
454         msg1 = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %ss muscles.");
455     } else {
456         msg1 = _("%sが%sの筋肉から力を吸いとった。", "%^s drains power from %s's muscles.");
457     }
458
459     resist = ((tr_ptr->flags1 & RF1_UNIQUE) != 0);
460     saving_throw = (tr_ptr->level > randint1((rlev - 10) < 1 ? 1 : (rlev - 10)) + 10);
461
462     spell_badstatus_message(target_ptr, m_idx, t_idx, msg1, _("%^sには効果がなかった。", "%^s is unaffected."),
463         _("%^sには効果がなかった。", "%^s is unaffected."), _("%sの動きが遅くなった。", "%^s starts moving slower."), resist, saving_throw, TARGET_TYPE);
464
465     if (!resist && !saving_throw) {
466         set_monster_slow(target_ptr, t_idx, monster_slow_remaining(t_ptr) + 50);
467     }
468 }
469
470 /*!
471  * @brief RF6_HEALの処理。治癒。 /
472  * @param target_ptr プレーヤーへの参照ポインタ
473  * @param m_idx 呪文を唱えるモンスターID
474  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
475  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
476  */
477 void spell_RF6_HEAL(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
478 {
479     floor_type *floor_ptr = target_ptr->current_floor_ptr;
480     monster_type *m_ptr = &floor_ptr->m_list[m_idx];
481     DEPTH rlev = monster_level_idx(floor_ptr, m_idx);
482     bool seen = (!target_ptr->blind && m_ptr->ml);
483     GAME_TEXT m_name[MAX_NLEN];
484     monster_name(target_ptr, m_idx, m_name);
485     char m_poss[10];
486     monster_desc(target_ptr, m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
487
488     disturb(target_ptr, TRUE, TRUE);
489
490     monspell_message_base(target_ptr, m_idx, t_idx, _("%^sが何かをつぶやいた。", "%^s mumbles."),
491         _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss)),
492         _("%^sが自分の傷に集中した。", format("%%^s concentrates on %s wounds.", m_poss)),
493         _("%^sは自分の傷に念を集中した。", format("%%^s concentrates on %s wounds.", m_poss)), target_ptr->blind > 0, TARGET_TYPE);
494
495     m_ptr->hp += (rlev * 6);
496     if (m_ptr->hp >= m_ptr->maxhp) {
497         /* Fully healed */
498         m_ptr->hp = m_ptr->maxhp;
499
500         monspell_message_base(target_ptr, m_idx, t_idx, _("%^sは完全に治ったようだ!", "%^s sounds completely healed!"),
501             _("%^sは完全に治ったようだ!", "%^s sounds completely healed!"), _("%^sは完全に治った!", "%^s looks completely healed!"),
502             _("%^sは完全に治った!", "%^s looks completely healed!"), !seen, TARGET_TYPE);
503     } else {
504         monspell_message_base(target_ptr, m_idx, t_idx, _("%^sは体力を回復したようだ。", "%^s sounds healthier."),
505             _("%^sは体力を回復したようだ。", "%^s sounds healthier."), _("%^sは体力を回復したようだ。", "%^s looks healthier."),
506             _("%^sは体力を回復したようだ。", "%^s looks healthier."), !seen, TARGET_TYPE);
507     }
508
509     if (target_ptr->health_who == m_idx)
510         target_ptr->redraw |= (PR_HEALTH);
511     if (target_ptr->riding == m_idx)
512         target_ptr->redraw |= (PR_UHEALTH);
513
514     if (!monster_fear_remaining(m_ptr))
515         return;
516
517     (void)set_monster_monfear(target_ptr, m_idx, 0);
518
519     if (see_monster(target_ptr, m_idx))
520         msg_format(_("%^sは勇気を取り戻した。", format("%%^s recovers %s courage.", m_poss)), m_name);
521 }
522
523 /*!
524  * @brief RF6_INVULNERの処理。無敵。 /
525  * @param target_ptr プレーヤーへの参照ポインタ
526  * @param m_idx 呪文を唱えるモンスターID
527  * @param t_idx 呪文を受けるモンスターID。プレイヤーの場合はdummyで0とする。
528  * @param TARGET_TYPE プレイヤーを対象とする場合MONSTER_TO_PLAYER、モンスターを対象とする場合MONSTER_TO_MONSTER
529  */
530 void spell_RF6_INVULNER(player_type *target_ptr, MONSTER_IDX m_idx, MONSTER_IDX t_idx, int TARGET_TYPE)
531 {
532     monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
533     bool seen = (!target_ptr->blind && m_ptr->ml);
534
535     monspell_message_base(target_ptr, m_idx, t_idx, _("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."),
536         _("%^sが何かを力強くつぶやいた。", "%^s mumbles powerfully."), _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."),
537         _("%sは無傷の球の呪文を唱えた。", "%^s casts a Globe of Invulnerability."), !seen, TARGET_TYPE);
538
539     MONRACE_IDX r_idx = m_ptr->r_idx;
540     if ((r_idx == MON_MARIO) || r_idx == MON_LUIGI) {
541         GAME_TEXT m_name[MAX_NLEN];
542         monster_desc(target_ptr, m_name, m_ptr, MD_NONE);
543         msg_format(_("%sはスターを取った!", "%^s got a star!"), m_name);
544     }
545
546     if (!monster_invulner_remaining(m_ptr))
547         (void)set_monster_invulner(target_ptr, m_idx, randint1(4) + 4, FALSE);
548 }
549
550 /*!
551  * @brief RF6_FORGETの処理。記憶消去。 /
552  * @param target_ptr プレーヤーへの参照ポインタ
553  * @param m_idx 呪文を唱えるモンスターID
554  * @param なし
555  */
556 void spell_RF6_FORGET(player_type *target_ptr, MONSTER_IDX m_idx)
557 {
558     DEPTH rlev = monster_level_idx(target_ptr->current_floor_ptr, m_idx);
559     GAME_TEXT m_name[MAX_NLEN];
560     monster_name(target_ptr, m_idx, m_name);
561
562     disturb(target_ptr, TRUE, TRUE);
563
564     msg_format(_("%^sがあなたの記憶を消去しようとしている。", "%^s tries to blank your mind."), m_name);
565
566     if (randint0(100 + rlev / 2) < target_ptr->skill_sav) {
567         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
568     } else if (lose_all_info(target_ptr)) {
569         msg_print(_("記憶が薄れてしまった。", "Your memories fade away."));
570     }
571
572     learn_spell(target_ptr, MS_FORGET);
573 }