OSDN Git Service

bee2df7842bfcb28e7c4440669d0d2a96fcf7324
[hengbandforosx/hengbandosx.git] / src / effect / effect-monster.cpp
1 /*!
2  * @brief 魔法によるモンスターへの効果まとめ
3  * @date 2020/04/29
4  * @author Hourier
5  */
6
7 #include "effect/effect-monster.h"
8 #include "core/disturbance.h"
9 #include "core/player-redraw-types.h"
10 #include "core/stuff-handler.h"
11 #include "core/window-redrawer.h"
12 #include "effect/effect-characteristics.h"
13 #include "effect/effect-monster-util.h"
14 #include "effect/effect-monster-switcher.h"
15 #include "floor/cave.h"
16 #include "floor/floor-object.h"
17 #include "game-option/play-record-options.h"
18 #include "grid/grid.h"
19 #include "io/write-diary.h"
20 #include "main/sound-definitions-table.h"
21 #include "main/sound-of-music.h"
22 #include "monster-floor/monster-death.h"
23 #include "monster-floor/monster-move.h"
24 #include "monster-floor/monster-remover.h"
25 #include "monster-race/monster-race.h"
26 #include "monster-race/race-flags-resistance.h"
27 #include "monster-race/race-flags1.h"
28 #include "monster-race/race-flags3.h"
29 #include "monster-race/race-flags7.h"
30 #include "monster-race/race-indice-types.h"
31 #include "monster/monster-describer.h"
32 #include "monster/monster-description-types.h"
33 #include "monster/monster-info.h"
34 #include "monster/monster-status-setter.h"
35 #include "monster/monster-status.h"
36 #include "monster/monster-update.h"
37 #include "object-enchant/special-object-flags.h"
38 #include "object/object-generator.h"
39 #include "object/object-kind-hook.h"
40 #include "player-info/avatar.h"
41 #include "util/bit-flags-calculator.h"
42 #include "spell-kind/blood-curse.h"
43 #include "spell-kind/spells-polymorph.h"
44 #include "spell-kind/spells-teleport.h"
45 #include "spell/spell-types.h"
46 #include "spells-effect-util.h"
47 #include "sv-definition/sv-other-types.h"
48 #include "system/floor-type-definition.h"
49 #include "system/monster-type-definition.h"
50 #include "system/monster-race-definition.h"
51 #include "system/object-type-definition.h"
52 #include "system/player-type-definition.h"
53 #include "view/display-messages.h"
54
55 /*!
56  * @brief ビーム/ボルト/ボール系魔法によるモンスターへの効果があるかないかを判定する
57  * @param caster_ptr プレーヤーへの参照ポインタ
58  * @param em_ptr モンスター効果構造体への参照ポインタ
59  * @return 効果が何もないならFALSE、何かあるならTRUE
60  */
61 static process_result is_affective(player_type *caster_ptr, effect_monster_type *em_ptr)
62 {
63     if (!em_ptr->g_ptr->m_idx)
64         return PROCESS_FALSE;
65     if (em_ptr->who && (em_ptr->g_ptr->m_idx == em_ptr->who))
66         return PROCESS_FALSE;
67     if (sukekaku && ((em_ptr->m_ptr->r_idx == MON_SUKE) || (em_ptr->m_ptr->r_idx == MON_KAKU)))
68         return PROCESS_FALSE;
69     if (em_ptr->m_ptr->hp < 0)
70         return PROCESS_FALSE;
71     if (em_ptr->who || em_ptr->g_ptr->m_idx != caster_ptr->riding)
72         return PROCESS_TRUE;
73
74     switch (em_ptr->effect_type) {
75     case GF_OLD_HEAL:
76     case GF_OLD_SPEED:
77     case GF_STAR_HEAL:
78         return PROCESS_TRUE;
79     case GF_OLD_SLOW:
80     case GF_OLD_SLEEP:
81     case GF_OLD_CLONE:
82     case GF_OLD_CONF:
83     case GF_OLD_POLY:
84     case GF_GENOCIDE:
85     case GF_E_GENOCIDE:
86         return PROCESS_CONTINUE;
87     default:
88         break;
89     }
90
91     return PROCESS_FALSE;
92 }
93
94 /*!
95  * @brief 魔法の効果やモンスター種別(MAKE/FEMALE/なし)に応じて表示するメッセージを変更する
96  * @param caster_ptr プレーヤーへの参照ポインタ
97  * @param em_ptr モンスター効果構造体への参照ポインタ
98  */
99 static void make_description_of_affecred_monster(player_type *caster_ptr, effect_monster_type *em_ptr)
100 {
101     em_ptr->dam = (em_ptr->dam + em_ptr->r) / (em_ptr->r + 1);
102     monster_desc(caster_ptr, em_ptr->m_name, em_ptr->m_ptr, 0);
103     monster_desc(caster_ptr, em_ptr->m_poss, em_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
104 }
105
106 /*!
107  * @brief モンスターへの効果属性による耐性及び効果を処理する( / Proccess affecting to monster by effect.
108  * @param caster_ptr プレーヤーへの参照ポインタ
109  * @param em_ptr モンスター効果構造体への参照ポインタ
110  * @return 完全な耐性が発動したらCONTINUE、そうでないなら効果処理の結果
111  * @details
112  * 完全な耐性を持っていたら、一部属性を除いて影響は及ぼさない
113  * 射撃属性 (デバッグ用)であれば貫通する
114  */
115 static process_result exe_affect_monster_by_effect(player_type *caster_ptr, effect_monster_type *em_ptr)
116 {
117     process_result result = is_affective(caster_ptr, em_ptr);
118     if (result != PROCESS_TRUE) {
119         if (result == PROCESS_CONTINUE) {
120             em_ptr->note = _("には効果がなかった。", " is unaffected.");
121             em_ptr->dam = 0;
122         }
123         return result;
124     }
125
126     if (none_bits(em_ptr->r_ptr->flagsr, RFR_RES_ALL) || em_ptr->effect_type == GF_OLD_CLONE || em_ptr->effect_type == GF_STAR_HEAL
127         || em_ptr->effect_type == GF_OLD_HEAL || em_ptr->effect_type == GF_OLD_SPEED || em_ptr->effect_type == GF_CAPTURE || em_ptr->effect_type == GF_PHOTO)
128         return switch_effects_monster(caster_ptr, em_ptr);
129
130     if (any_bits(em_ptr->r_ptr->flagsr, RFR_RES_ALL) && (em_ptr->effect_type == GF_ARROW))
131         return switch_effects_monster(caster_ptr, em_ptr);
132
133     em_ptr->note = _("には完全な耐性がある!", " is immune.");
134     em_ptr->dam = 0;
135     if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
136         em_ptr->r_ptr->r_flagsr |= (RFR_RES_ALL);
137
138     if (em_ptr->effect_type == GF_LITE_WEAK || em_ptr->effect_type == GF_KILL_WALL)
139         em_ptr->skipped = TRUE;
140
141     return PROCESS_CONTINUE;
142 }
143
144 /*!
145  * @brief ペットの死亡を処理する
146  * @param caster_ptr プレーヤーへの参照ポインタ
147  * @param em_ptr モンスター効果構造体への参照ポインタ
148  */
149 static void effect_damage_killed_pet(player_type *caster_ptr, effect_monster_type *em_ptr)
150 {
151     bool sad = is_pet(em_ptr->m_ptr) && !(em_ptr->m_ptr->ml);
152     if (em_ptr->known && em_ptr->note) {
153         monster_desc(caster_ptr, em_ptr->m_name, em_ptr->m_ptr, MD_TRUE_NAME);
154         if (em_ptr->see_s_msg)
155             msg_format("%^s%s", em_ptr->m_name, em_ptr->note);
156         else
157             caster_ptr->current_floor_ptr->monster_noise = TRUE;
158     }
159
160     if (em_ptr->who > 0)
161         monster_gain_exp(caster_ptr, em_ptr->who, em_ptr->m_ptr->r_idx);
162
163     monster_death(caster_ptr, em_ptr->g_ptr->m_idx, FALSE);
164     delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
165     if (sad)
166         msg_print(_("少し悲しい気分がした。", "You feel sad for a moment."));
167 }
168
169 /*!
170  * @brief モンスターの睡眠を処理する
171  * @param caster_ptr プレーヤーへの参照ポインタ
172  * @param em_ptr モンスター効果構造体への参照ポインタ
173  */
174 static void effect_damage_makes_sleep(player_type *caster_ptr, effect_monster_type *em_ptr)
175 {
176     if (em_ptr->note && em_ptr->seen_msg)
177         msg_format("%^s%s", em_ptr->m_name, em_ptr->note);
178     else if (em_ptr->see_s_msg)
179         message_pain(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam);
180     else
181         caster_ptr->current_floor_ptr->monster_noise = TRUE;
182
183     if (em_ptr->do_sleep)
184         (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_sleep);
185 }
186
187 /*!
188  * @brief モンスターからモンスターへのダメージを処理する / Hurt the monster by damages another monster did.
189  * @param caster_ptr プレイヤーへの参照ポインタ
190  * @param em_ptr モンスター効果構造体への参照ポインタ
191  * @return ダメージを処理しなかった(モンスターIDがプレイヤー自身)場合はFALSE、処理した(モンスターだった)場合TRUE
192  * @details
193  * モンスターIDがプレイヤー(0)の場合は処理しない。
194  */
195 static bool deal_effect_damage_from_monster(player_type *caster_ptr, effect_monster_type *em_ptr)
196 {
197     if (em_ptr->who <= 0)
198         return FALSE;
199
200     if (caster_ptr->health_who == em_ptr->g_ptr->m_idx)
201         caster_ptr->redraw |= (PR_HEALTH);
202     if (caster_ptr->riding == em_ptr->g_ptr->m_idx)
203         caster_ptr->redraw |= (PR_UHEALTH);
204
205     (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, 0);
206     em_ptr->m_ptr->hp -= em_ptr->dam;
207     if (em_ptr->m_ptr->hp < 0)
208         effect_damage_killed_pet(caster_ptr, em_ptr);
209     else
210         effect_damage_makes_sleep(caster_ptr, em_ptr);
211
212     return TRUE;
213 }
214
215 /*!
216  * @brief 不潔な病人の治療処理
217  * @param caster_ptr プレーヤーへの参照ポインタ
218  * @param em_ptr モンスター効果構造体への参照ポインタ
219  * @return 大賞モンスターが不潔な病人だった場合はTRUE、それ以外はFALSE
220  */
221 static bool heal_leaper(player_type *caster_ptr, effect_monster_type *em_ptr)
222 {
223     if (!em_ptr->heal_leper)
224         return FALSE;
225
226     if (em_ptr->seen_msg)
227         msg_print(_("不潔な病人は病気が治った!", "The Mangy looking leper is healed!"));
228
229     if (record_named_pet && is_pet(em_ptr->m_ptr) && em_ptr->m_ptr->nickname) {
230         char m2_name[MAX_NLEN];
231         monster_desc(caster_ptr, m2_name, em_ptr->m_ptr, MD_INDEF_VISIBLE);
232         exe_write_diary(caster_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_HEAL_LEPER, m2_name);
233     }
234
235     delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
236     return TRUE;
237 }
238
239 /*!
240  * @brief プレイヤー起因の効果によるダメージを処理 / Deal damages from player and fear by them.
241  * @param caster_ptr プレーヤーへの参照ポインタ
242  * @param em_ptr モンスター効果構造体への参照ポインタ
243  * @return モンスターが死んだらTRUE、生きていたらFALSE
244  * @details
245  * em_ptr->do_fearによる恐怖メッセージもここで表示。
246  */
247 static bool deal_effect_damage_from_player(player_type *caster_ptr, effect_monster_type *em_ptr)
248 {
249     bool fear = FALSE;
250     if (mon_take_hit(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam, &fear, em_ptr->note_dies))
251         return TRUE;
252
253     if (em_ptr->do_sleep)
254         anger_monster(caster_ptr, em_ptr->m_ptr);
255
256     if (em_ptr->note && em_ptr->seen)
257         msg_format(_("%s%s", "%^s%s"), em_ptr->m_name, em_ptr->note);
258     else if (em_ptr->known && (em_ptr->dam || !em_ptr->do_fear))
259         message_pain(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam);
260
261     if (((em_ptr->dam > 0) || em_ptr->get_angry) && !em_ptr->do_sleep)
262         anger_monster(caster_ptr, em_ptr->m_ptr);
263
264     if ((fear || em_ptr->do_fear) && em_ptr->seen) {
265         sound(SOUND_FLEE);
266         msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), em_ptr->m_name);
267     }
268
269     return FALSE;
270 }
271
272 /*!
273  * @brief モンスターに効果のダメージを与える / Deal effect damage to monster.
274  * @param caster_ptr プレーヤーへの参照ポインタ
275  * @param em_ptr モンスター効果構造体への参照ポインタ
276  * @details
277  * 以下のいずれかの処理を行う。
278  * 1.モンスターによる効果ダメージの処理
279  * 2.不潔な病人を癒す処理
280  * 3.プレイヤーによる効果ダメージの処理
281  * 4.睡眠する処理
282  */
283 static void deal_effect_damage_to_monster(player_type *caster_ptr, effect_monster_type *em_ptr)
284 {
285     if (em_ptr->effect_type == GF_DRAIN_MANA)
286         return;
287
288     // モンスターによる効果
289     if (deal_effect_damage_from_monster(caster_ptr, em_ptr))
290         return;
291
292     //プレイヤーによる効果
293     if (heal_leaper(caster_ptr, em_ptr))
294         return;
295     if (deal_effect_damage_from_player(caster_ptr, em_ptr))
296         return;
297
298     if (em_ptr->do_sleep)
299         (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_sleep);
300 }
301
302 /*!
303  * @brief プレイヤーが眠っている敵に効果を及ぼした場合の徳の変化
304  * @param caster_ptr プレーヤーへの参照ポインタ
305  * @param em_ptr モンスター効果構造体への参照ポインタ
306  */
307 static void effect_makes_change_virtues(player_type *caster_ptr, effect_monster_type *em_ptr)
308 {
309     if ((em_ptr->who > 0) || !em_ptr->slept)
310         return;
311
312     if (!(em_ptr->r_ptr->flags3 & RF3_EVIL) || one_in_(5))
313         chg_virtue(caster_ptr, V_COMPASSION, -1);
314     if (!(em_ptr->r_ptr->flags3 & RF3_EVIL) || one_in_(5))
315         chg_virtue(caster_ptr, V_HONOUR, -1);
316 }
317
318 /*!
319  * @brief 魔法効果に対する強制処理(変身の強制解除、死なない処理)
320  * @param caster_ptr プレーヤーへの参照ポインタ
321  * @param em_ptr モンスター効果構造体への参照ポインタ
322  */
323 static void affected_monster_prevents_bad_status(player_type *caster_ptr, effect_monster_type *em_ptr)
324 {
325     if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) || (em_ptr->r_ptr->flags1 & RF1_QUESTOR) || (caster_ptr->riding && (em_ptr->g_ptr->m_idx == caster_ptr->riding)))
326         em_ptr->do_polymorph = FALSE;
327
328     if (((em_ptr->r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) || (em_ptr->r_ptr->flags7 & RF7_NAZGUL)) && !caster_ptr->phase_out && (em_ptr->who > 0)
329         && (em_ptr->dam > em_ptr->m_ptr->hp))
330         em_ptr->dam = em_ptr->m_ptr->hp;
331 }
332
333 /*!
334  * @brief モンスターの朦朧値を蓄積させる
335  * @param caster_ptr プレーヤーへの参照ポインタ
336  * @param em_ptr モンスター効果構造体への参照ポインタ
337  * @param stun_damage 朦朧値
338  */
339 static void effect_damage_piles_stun(player_type *caster_ptr, effect_monster_type *em_ptr)
340 {
341     if ((em_ptr->do_stun == 0) || (em_ptr->r_ptr->flagsr & (RFR_RES_SOUN | RFR_RES_WALL)) || (em_ptr->r_ptr->flags3 & RF3_NO_STUN))
342         return;
343
344     if (em_ptr->seen)
345         em_ptr->obvious = TRUE;
346
347     int turns = 0;
348     if (monster_stunned_remaining(em_ptr->m_ptr)) {
349         em_ptr->note = _("はひどくもうろうとした。", " is more dazed.");
350         turns = monster_stunned_remaining(em_ptr->m_ptr) + (em_ptr->do_stun / 2);
351     } else {
352         em_ptr->note = _("はもうろうとした。", " is dazed.");
353         turns = em_ptr->do_stun;
354     }
355
356     (void)set_monster_stunned(caster_ptr, em_ptr->g_ptr->m_idx, turns);
357     em_ptr->get_angry = TRUE;
358 }
359
360 /*!
361  * @brief モンスターの混乱値を蓄積させる
362  * @param caster_ptr プレーヤーへの参照ポインタ
363  * @param em_ptr モンスター効果構造体への参照ポインタ
364  * @param stun_damage 混乱値
365  */
366 static void effect_damage_piles_confusion(player_type *caster_ptr, effect_monster_type *em_ptr)
367 {
368     if ((em_ptr->do_conf == 0) || (em_ptr->r_ptr->flags3 & RF3_NO_CONF) || (em_ptr->r_ptr->flagsr & RFR_EFF_RES_CHAO_MASK))
369         return;
370
371     if (em_ptr->seen)
372         em_ptr->obvious = TRUE;
373
374     int turns = 0;
375     if (monster_confused_remaining(em_ptr->m_ptr)) {
376         em_ptr->note = _("はさらに混乱したようだ。", " looks more confused.");
377         turns = monster_confused_remaining(em_ptr->m_ptr) + (em_ptr->do_conf / 2);
378     } else {
379         em_ptr->note = _("は混乱したようだ。", " looks confused.");
380         turns = em_ptr->do_conf;
381     }
382
383     (void)set_monster_confused(caster_ptr, em_ptr->g_ptr->m_idx, turns);
384     em_ptr->get_angry = TRUE;
385 }
386
387 /*!
388  * @brief モンスターの恐怖値を蓄積させる
389  * @param caster_ptr プレーヤーへの参照ポインタ
390  * @param em_ptr モンスター効果構造体への参照ポインタ
391  * @param stun_damage 恐怖値
392  * @details
393  * 打撃ダメージによる恐怖もあるため、メッセージは後で表示。
394  */
395 static void effect_damage_piles_fear(player_type *caster_ptr, effect_monster_type *em_ptr)
396 {
397     if (em_ptr->do_fear == 0 || any_bits(em_ptr->r_ptr->flags3, RF3_NO_FEAR))
398         return;
399
400     (void)set_monster_monfear(caster_ptr, em_ptr->g_ptr->m_idx, monster_fear_remaining(em_ptr->m_ptr) + em_ptr->do_fear);
401     em_ptr->get_angry = TRUE;
402 }
403
404 /*!
405  * @brief モンスターを衰弱させる
406  * @param em_ptr モンスター効果構造体への参照ポインタ
407  */
408 static void effect_damage_makes_weak(effect_monster_type *em_ptr)
409 {
410     if (em_ptr->do_time == 0)
411         return;
412
413     if (em_ptr->seen)
414         em_ptr->obvious = TRUE;
415
416     if (em_ptr->do_time >= em_ptr->m_ptr->maxhp)
417         em_ptr->do_time = em_ptr->m_ptr->maxhp - 1;
418
419     if (em_ptr->do_time) {
420         em_ptr->note = _("は弱くなったようだ。", " seems weakened.");
421         em_ptr->m_ptr->maxhp -= em_ptr->do_time;
422         if ((em_ptr->m_ptr->hp - em_ptr->dam) > em_ptr->m_ptr->maxhp)
423             em_ptr->dam = em_ptr->m_ptr->hp - em_ptr->m_ptr->maxhp;
424     }
425
426     em_ptr->get_angry = TRUE;
427 }
428
429 /*!
430  * @brief モンスターを変身させる
431  * @param caster_ptr プレーヤーへの参照ポインタ
432  * @param em_ptr モンスター効果構造体への参照ポインタ
433  */
434 static void effect_damage_makes_polymorph(player_type *caster_ptr, effect_monster_type *em_ptr)
435 {
436     if (!em_ptr->do_polymorph || (randint1(90) <= em_ptr->r_ptr->level))
437         return;
438
439     if (polymorph_monster(caster_ptr, em_ptr->y, em_ptr->x)) {
440         if (em_ptr->seen)
441             em_ptr->obvious = TRUE;
442
443         em_ptr->note = _("が変身した!", " changes!");
444         em_ptr->dam = 0;
445     }
446
447     em_ptr->m_ptr = &caster_ptr->current_floor_ptr->m_list[em_ptr->g_ptr->m_idx];
448     em_ptr->r_ptr = &r_info[em_ptr->m_ptr->r_idx];
449 }
450
451 /*!
452  * @brief モンスターをテレポートさせる
453  * @param caster_ptr プレーヤーへの参照ポインタ
454  * @param em_ptr モンスター効果構造体への参照ポインタ
455  */
456 static void effect_damage_makes_teleport(player_type *caster_ptr, effect_monster_type *em_ptr)
457 {
458     if (em_ptr->do_dist == 0)
459         return;
460
461     if (em_ptr->seen)
462         em_ptr->obvious = TRUE;
463
464     em_ptr->note = _("が消え去った!", " disappears!");
465
466     if (!em_ptr->who)
467         chg_virtue(caster_ptr, V_VALOUR, -1);
468
469     teleport_flags tflag = static_cast<teleport_flags>((!em_ptr->who ? TELEPORT_DEC_VALOUR : TELEPORT_SPONTANEOUS) | TELEPORT_PASSIVE);
470     teleport_away(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_dist, tflag);
471
472     em_ptr->y = em_ptr->m_ptr->fy;
473     em_ptr->x = em_ptr->m_ptr->fx;
474     em_ptr->g_ptr = &caster_ptr->current_floor_ptr->grid_array[em_ptr->y][em_ptr->x];
475 }
476
477 /*!
478  * @brief モンスターへのダメージに応じたメッセージを表示させ、異常状態を与える
479  * @param caster_ptr プレーヤーへの参照ポインタ
480  * @param em_ptr モンスター効果構造体への参照ポインタ
481  * @details
482  * 以下の判定と処理を行う。
483  * 1.全耐性または無敵でダメージが通らなかった場合
484  * 2.ダメージ量が現HPを上回る場合
485  * 3.通常時(デバフをかける)
486  */
487 static void effect_damage_gives_bad_status(player_type *caster_ptr, effect_monster_type *em_ptr)
488 {
489     int tmp_damage = em_ptr->dam;
490     em_ptr->dam = mon_damage_mod(caster_ptr, em_ptr->m_ptr, em_ptr->dam, (bool)(em_ptr->effect_type == GF_PSY_SPEAR));
491     if ((tmp_damage > 0) && (em_ptr->dam == 0) && em_ptr->seen)
492         em_ptr->note = _("はダメージを受けていない。", " is unharmed.");
493
494     if (em_ptr->dam > em_ptr->m_ptr->hp)
495         em_ptr->note = em_ptr->note_dies;
496     else {
497         effect_damage_piles_stun(caster_ptr, em_ptr);
498         effect_damage_piles_confusion(caster_ptr, em_ptr);
499         effect_damage_piles_fear(caster_ptr, em_ptr);
500         effect_damage_makes_weak(em_ptr);
501         effect_damage_makes_polymorph(caster_ptr, em_ptr);
502         effect_damage_makes_teleport(caster_ptr, em_ptr);
503     }
504 }
505
506 /*!
507  * @brief 効果によるモンスターへのダメージと付随効果を処理する
508  * @param caster_ptr プレーヤーへの参照ポインタ
509  * @param em_ptr モンスター効果構造体への参照ポインタ
510  * @details
511  * 以下の処理を行う。
512  * 1.奇襲による徳の変化
513  * 2.完全な耐性及び無敵によるダメージのカット
514  * 3.ダメージによる付随効果の処理(混乱/朦朧/恐怖/衰弱/変身/テレポート)
515  * 4.ダメージ処理及び恐怖メッセージ
516  * 5.悪魔領域血の呪いによる事後処理
517  */
518 static void exe_affect_monster_by_damage(player_type *caster_ptr, effect_monster_type *em_ptr)
519 {
520     effect_makes_change_virtues(caster_ptr, em_ptr);
521     affected_monster_prevents_bad_status(caster_ptr, em_ptr);
522     effect_damage_gives_bad_status(caster_ptr, em_ptr);
523     deal_effect_damage_to_monster(caster_ptr, em_ptr);
524     if ((em_ptr->effect_type == GF_BLOOD_CURSE) && one_in_(4))
525         blood_curse_to_enemy(caster_ptr, em_ptr->who);
526 }
527
528 /*!
529  * @brief モンスター闘技場にいる場合の画面更新処理
530  * @param caster_ptr プレーヤーへの参照ポインタ
531  * @param em_ptr モンスター効果構造体への参照ポインタ
532  */
533 static void update_phase_out_stat(player_type *caster_ptr, effect_monster_type *em_ptr)
534 {
535     if (!caster_ptr->phase_out)
536         return;
537
538     caster_ptr->health_who = em_ptr->g_ptr->m_idx;
539     caster_ptr->redraw |= (PR_HEALTH);
540     handle_stuff(caster_ptr);
541 }
542
543 /*!
544  * @brief 魔法効果がペットに及んだ時の処理
545  * @param caster_ptr プレーヤーへの参照ポインタ
546  * @param em_ptr モンスター効果構造体への参照ポインタ
547  */
548 static void postprocess_by_effected_pet(player_type *caster_ptr, effect_monster_type *em_ptr)
549 {
550     if ((em_ptr->dam <= 0) || is_pet(em_ptr->m_ptr) || is_friendly(em_ptr->m_ptr))
551         return;
552
553     if (em_ptr->who == 0) {
554         if (!(em_ptr->flag & PROJECT_NO_HANGEKI))
555             set_target(em_ptr->m_ptr, monster_target_y, monster_target_x);
556
557         return;
558     }
559
560     if ((em_ptr->who > 0) && is_pet(em_ptr->m_caster_ptr) && !player_bold(caster_ptr, em_ptr->m_ptr->target_y, em_ptr->m_ptr->target_x))
561         set_target(em_ptr->m_ptr, em_ptr->m_caster_ptr->fy, em_ptr->m_caster_ptr->fx);
562 }
563
564 /*!
565  * @brief 魔法効果が騎乗モンスターに及んだ時の処理
566  * @param caster_ptr プレーヤーへの参照ポインタ
567  * @param em_ptr モンスター効果構造体への参照ポインタ
568  */
569 static void postprocess_by_riding_pet_effected(player_type *caster_ptr, effect_monster_type *em_ptr)
570 {
571     if (!caster_ptr->riding || (caster_ptr->riding != em_ptr->g_ptr->m_idx) || (em_ptr->dam <= 0))
572         return;
573
574     if (em_ptr->m_ptr->hp > (em_ptr->m_ptr->maxhp / 3))
575         em_ptr->dam = (em_ptr->dam + 1) / 2;
576
577     rakubadam_m = (em_ptr->dam > 200) ? 200 : em_ptr->dam;
578 }
579
580 /*!
581  * @brief 写真を撮った時の処理
582  * @param caster_ptr プレーヤーへの参照ポインタ
583  * @param em_ptr モンスター効果構造体への参照ポインタ
584  * @details 写真のフラッシュは弱閃光属性
585  */
586 static void postprocess_by_taking_photo(player_type *caster_ptr, effect_monster_type *em_ptr)
587 {
588     if (em_ptr->photo == 0)
589         return;
590
591     object_type *q_ptr;
592     object_type forge;
593     q_ptr = &forge;
594     object_prep(caster_ptr, q_ptr, lookup_kind(TV_STATUE, SV_PHOTO));
595     q_ptr->pval = em_ptr->photo;
596     q_ptr->ident |= (IDENT_FULL_KNOWN);
597     (void)drop_near(caster_ptr, q_ptr, -1, caster_ptr->y, caster_ptr->x);
598 }
599
600 /*!
601  * @brief モンスター効果の後処理 (ペット関係、記念撮影、グローバル変数更新)
602  * @param caster_ptr プレーヤーへの参照ポインタ
603  * @param em_ptr モンスター効果構造体への参照ポインタ
604  */
605 static void exe_affect_monster_postprocess(player_type *caster_ptr, effect_monster_type *em_ptr)
606 {
607     postprocess_by_effected_pet(caster_ptr, em_ptr);
608     postprocess_by_riding_pet_effected(caster_ptr, em_ptr);
609     postprocess_by_taking_photo(caster_ptr, em_ptr);
610     project_m_n++;
611     project_m_x = em_ptr->x;
612     project_m_y = em_ptr->y;
613 }
614
615 /*!
616  * @brief 汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.
617  * @param caster_ptr プレーヤーへの参照ポインタ
618  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
619  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
620  * @param y 目標y座標 / Target y location (or location to travel "towards")
621  * @param x 目標x座標 / Target x location (or location to travel "towards")
622  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
623  * @param effect_type 効果属性 / Type of damage to apply to monsters (and objects)
624  * @param flag 効果フラグ
625  * @param see_s_msg TRUEならばメッセージを表示する
626  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
627  * @details
628  * 以下の処理を行う。
629  * 1.魔法効果による効果に対する耐性による軽減計算及び効果の発動
630  * 2.魔法効果によるダメージの処理とダメージによる効果の発動
631  * 3.ペット及び撮影による事後効果
632  */
633 bool affect_monster(
634     player_type *caster_ptr, MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID effect_type, BIT_FLAGS flag, bool see_s_msg)
635 {
636     effect_monster_type tmp_effect;
637     effect_monster_type *em_ptr = initialize_effect_monster(caster_ptr, &tmp_effect, who, r, y, x, dam, effect_type, flag, see_s_msg);
638
639     make_description_of_affecred_monster(caster_ptr, em_ptr);
640
641     if (caster_ptr->riding && (em_ptr->g_ptr->m_idx == caster_ptr->riding))
642         disturb(caster_ptr, TRUE, TRUE);
643
644     process_result result = exe_affect_monster_by_effect(caster_ptr, em_ptr);
645     if (result != PROCESS_CONTINUE)
646         return (bool)result;
647
648     if (em_ptr->skipped)
649         return FALSE;
650
651     exe_affect_monster_by_damage(caster_ptr, em_ptr);
652
653     update_phase_out_stat(caster_ptr, em_ptr);
654     if (em_ptr->m_ptr->r_idx)
655         update_monster(caster_ptr, em_ptr->g_ptr->m_idx, FALSE);
656
657     lite_spot(caster_ptr, em_ptr->y, em_ptr->x);
658     if ((caster_ptr->monster_race_idx == em_ptr->m_ptr->r_idx) && (em_ptr->seen || !em_ptr->m_ptr->r_idx))
659         caster_ptr->window_flags |= (PW_MONSTER);
660
661     exe_affect_monster_postprocess(caster_ptr, em_ptr);
662     return em_ptr->obvious;
663 }