2 * @brief 魔法によるモンスターへの効果まとめ
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-switcher.h"
14 #include "floor/cave.h"
15 #include "floor/floor-object.h"
16 #include "game-option/play-record-options.h"
17 #include "io/write-diary.h"
18 #include "main/sound-definitions-table.h"
19 #include "main/sound-of-music.h"
20 #include "monster-floor/monster-death.h"
21 #include "monster-floor/monster-move.h"
22 #include "monster-floor/monster-remover.h"
23 #include "monster-race/monster-race.h"
24 #include "monster-race/race-flags-resistance.h"
25 #include "monster-race/race-flags1.h"
26 #include "monster-race/race-flags3.h"
27 #include "monster-race/race-flags7.h"
28 #include "monster-race/race-indice-types.h"
29 #include "monster/monster-describer.h"
30 #include "monster/monster-description-types.h"
31 #include "monster/monster-info.h"
32 #include "monster/monster-status-setter.h"
33 #include "monster/monster-status.h"
34 #include "monster/monster-update.h"
35 #include "object-enchant/special-object-flags.h"
36 #include "object/object-generator.h"
37 #include "object/object-kind-hook.h"
38 #include "player-info/avatar.h"
39 #include "spell-kind/blood-curse.h"
40 #include "spell-kind/spells-polymorph.h"
41 #include "spell-kind/spells-teleport.h"
42 #include "spell/spell-types.h"
43 #include "spells-effect-util.h"
44 #include "sv-definition/sv-other-types.h"
45 #include "system/floor-type-definition.h"
46 #include "system/object-type-definition.h"
47 #include "view/display-messages.h"
50 * @brief ビーム/ボルト/ボール系魔法によるモンスターへの効果があるかないかを判定する
51 * @param caster_ptr プレーヤーへの参照ポインタ
52 * @param em_ptr モンスター効果構造体への参照ポインタ
53 * @return 効果が何もないならFALSE、何かあるならTRUE
55 static bool is_never_effect(player_type *caster_ptr, effect_monster_type *em_ptr)
57 if (!em_ptr->g_ptr->m_idx)
59 if (em_ptr->who && (em_ptr->g_ptr->m_idx == em_ptr->who))
61 if ((em_ptr->g_ptr->m_idx == caster_ptr->riding) && !em_ptr->who && !(em_ptr->effect_type == GF_OLD_HEAL) && !(em_ptr->effect_type == GF_OLD_SPEED)
62 && !(em_ptr->effect_type == GF_STAR_HEAL))
64 if (sukekaku && ((em_ptr->m_ptr->r_idx == MON_SUKE) || (em_ptr->m_ptr->r_idx == MON_KAKU)))
66 if (em_ptr->m_ptr->hp < 0)
73 * @brief 魔法の効果やモンスター種別(MAKE/FEMALE/なし)に応じて表示するメッセージを変更する
74 * @param caster_ptr プレーヤーへの参照ポインタ
75 * @param em_ptr モンスター効果構造体への参照ポインタ
78 static void decide_spell_result_description(player_type *caster_ptr, effect_monster_type *em_ptr)
80 em_ptr->dam = (em_ptr->dam + em_ptr->r) / (em_ptr->r + 1);
81 monster_desc(caster_ptr, em_ptr->m_name, em_ptr->m_ptr, 0);
82 monster_desc(caster_ptr, em_ptr->m_poss, em_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
83 if (caster_ptr->riding && (em_ptr->g_ptr->m_idx == caster_ptr->riding))
84 disturb(caster_ptr, TRUE, TRUE);
88 * @brief 完全な耐性を持っていたら、モンスターへの効果処理をスキップする
89 * @param caster_ptr プレーヤーへの参照ポインタ
90 * @param em_ptr モンスター効果構造体への参照ポインタ
91 * @return 完全耐性ならCONTINUE、そうでないなら効果処理の結果
93 static process_result process_monster_perfect_resistance(player_type *caster_ptr, effect_monster_type *em_ptr)
95 if (((em_ptr->r_ptr->flagsr & RFR_RES_ALL) == 0) || em_ptr->effect_type == GF_OLD_CLONE || em_ptr->effect_type == GF_STAR_HEAL
96 || 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)
97 return switch_effects_monster(caster_ptr, em_ptr);
99 em_ptr->note = _("には完全な耐性がある!", " is immune.");
101 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
102 em_ptr->r_ptr->r_flagsr |= (RFR_RES_ALL);
104 if (em_ptr->effect_type == GF_LITE_WEAK || em_ptr->effect_type == GF_KILL_WALL)
105 em_ptr->skipped = TRUE;
107 return PROCESS_CONTINUE;
112 * @param caster_ptr プレーヤーへの参照ポインタ
113 * @param em_ptr モンスター効果構造体への参照ポインタ
116 static void process_pet_death(player_type *caster_ptr, effect_monster_type *em_ptr)
118 bool sad = is_pet(em_ptr->m_ptr) && !(em_ptr->m_ptr->ml);
119 if (em_ptr->known && em_ptr->note) {
120 monster_desc(caster_ptr, em_ptr->m_name, em_ptr->m_ptr, MD_TRUE_NAME);
121 if (em_ptr->see_s_msg)
122 msg_format("%^s%s", em_ptr->m_name, em_ptr->note);
124 caster_ptr->current_floor_ptr->monster_noise = TRUE;
128 monster_gain_exp(caster_ptr, em_ptr->who, em_ptr->m_ptr->r_idx);
130 monster_death(caster_ptr, em_ptr->g_ptr->m_idx, FALSE);
131 delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
133 msg_print(_("少し悲しい気分がした。", "You feel sad for a moment."));
137 * @brief モンスターの睡眠を処理する
138 * @param caster_ptr プレーヤーへの参照ポインタ
139 * @param em_ptr モンスター効果構造体への参照ポインタ
142 static void process_monster_sleep(player_type *caster_ptr, effect_monster_type *em_ptr)
144 if (em_ptr->note && em_ptr->seen_msg)
145 msg_format("%^s%s", em_ptr->m_name, em_ptr->note);
146 else if (em_ptr->see_s_msg)
147 message_pain(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam);
149 caster_ptr->current_floor_ptr->monster_noise = TRUE;
151 if (em_ptr->do_sleep)
152 (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_sleep);
156 * @brief モンスターの被ダメージを処理する / If another monster did the damage, hurt the monster by hand
157 * @param caster_ptr プレーヤーへの参照ポインタ
158 * @param em_ptr モンスター効果構造体への参照ポインタ
159 * @return モンスターIDがプレーヤー自身だった場合FALSE、モンスターだった場合TRUE
161 static bool process_monster_damage(player_type *caster_ptr, effect_monster_type *em_ptr)
163 if (em_ptr->who <= 0)
166 if (caster_ptr->health_who == em_ptr->g_ptr->m_idx)
167 caster_ptr->redraw |= (PR_HEALTH);
168 if (caster_ptr->riding == em_ptr->g_ptr->m_idx)
169 caster_ptr->redraw |= (PR_UHEALTH);
171 (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, 0);
172 em_ptr->m_ptr->hp -= em_ptr->dam;
173 if (em_ptr->m_ptr->hp < 0)
174 process_pet_death(caster_ptr, em_ptr);
176 process_monster_sleep(caster_ptr, em_ptr);
183 * @param caster_ptr プレーヤーへの参照ポインタ
184 * @param em_ptr モンスター効果構造体への参照ポインタ
185 * @return 大賞モンスターが不潔な病人だった場合はTRUE、それ以外はFALSE
187 static bool heal_leaper(player_type *caster_ptr, effect_monster_type *em_ptr)
189 if (!em_ptr->heal_leper)
192 if (em_ptr->seen_msg)
193 msg_print(_("不潔な病人は病気が治った!", "The Mangy looking leper is healed!"));
195 if (record_named_pet && is_pet(em_ptr->m_ptr) && em_ptr->m_ptr->nickname) {
196 char m2_name[MAX_NLEN];
197 monster_desc(caster_ptr, m2_name, em_ptr->m_ptr, MD_INDEF_VISIBLE);
198 exe_write_diary(caster_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_HEAL_LEPER, m2_name);
201 delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
206 * @brief モンスターの恐慌処理 / If the player did it, give him experience, check fear
207 * @param caster_ptr プレーヤーへの参照ポインタ
208 * @param em_ptr モンスター効果構造体への参照ポインタ
209 * @return モンスターが死んだらTRUE、生きていたらFALSE
211 static bool process_monster_fear(player_type *caster_ptr, effect_monster_type *em_ptr)
214 if (mon_take_hit(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam, &fear, em_ptr->note_dies))
217 if (em_ptr->do_sleep)
218 anger_monster(caster_ptr, em_ptr->m_ptr);
220 if (em_ptr->note && em_ptr->seen)
221 msg_format(_("%s%s", "%^s%s"), em_ptr->m_name, em_ptr->note);
222 else if (em_ptr->known && (em_ptr->dam || !em_ptr->do_fear))
223 message_pain(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam);
225 if (((em_ptr->dam > 0) || em_ptr->get_angry) && !em_ptr->do_sleep)
226 anger_monster(caster_ptr, em_ptr->m_ptr);
228 if ((fear || em_ptr->do_fear) && em_ptr->seen) {
230 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), em_ptr->m_name);
237 * todo 睡眠処理があるので、死に際とは言えない。適切な関数名に要修正
238 * @brief モンスターの死に際処理 (魔力吸収を除く)
239 * @param caster_ptr プレーヤーへの参照ポインタ
240 * @param em_ptr モンスター効果構造体への参照ポインタ
243 static void process_monster_last_moment(player_type *caster_ptr, effect_monster_type *em_ptr)
245 if (em_ptr->effect_type == GF_DRAIN_MANA)
248 if (process_monster_damage(caster_ptr, em_ptr))
250 if (heal_leaper(caster_ptr, em_ptr))
252 if (process_monster_fear(caster_ptr, em_ptr))
255 if (em_ptr->do_sleep)
256 (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_sleep);
260 * @brief 魔法の効果による汎用処理 (変身の有無、現在HPの減算、徳の変化)
261 * @param caster_ptr プレーヤーへの参照ポインタ
262 * @param em_ptr モンスター効果構造体への参照ポインタ
265 static void process_spell_result(player_type *caster_ptr, effect_monster_type *em_ptr)
267 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)))
268 em_ptr->do_polymorph = FALSE;
270 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)
271 && (em_ptr->dam > em_ptr->m_ptr->hp))
272 em_ptr->dam = em_ptr->m_ptr->hp;
274 if ((em_ptr->who > 0) || !em_ptr->slept)
277 if (!(em_ptr->r_ptr->flags3 & RF3_EVIL) || one_in_(5))
278 chg_virtue(caster_ptr, V_COMPASSION, -1);
279 if (!(em_ptr->r_ptr->flags3 & RF3_EVIL) || one_in_(5))
280 chg_virtue(caster_ptr, V_HONOUR, -1);
284 * @brief モンスターの朦朧値を蓄積させる
285 * @param caster_ptr プレーヤーへの参照ポインタ
286 * @param em_ptr モンスター効果構造体への参照ポインタ
287 * @param stun_damage 朦朧値
290 static void pile_monster_stun(player_type *caster_ptr, effect_monster_type *em_ptr, int *stun_damage)
292 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))
296 em_ptr->obvious = TRUE;
298 if (monster_stunned_remaining(em_ptr->m_ptr)) {
299 em_ptr->note = _("はひどくもうろうとした。", " is more dazed.");
300 *stun_damage = monster_stunned_remaining(em_ptr->m_ptr) + (em_ptr->do_stun / 2);
302 em_ptr->note = _("はもうろうとした。", " is dazed.");
303 *stun_damage = em_ptr->do_stun;
306 (void)set_monster_stunned(caster_ptr, em_ptr->g_ptr->m_idx, *stun_damage);
307 em_ptr->get_angry = TRUE;
311 * @brief モンスターの混乱値を蓄積させる
312 * @param caster_ptr プレーヤーへの参照ポインタ
313 * @param em_ptr モンスター効果構造体への参照ポインタ
314 * @param stun_damage 混乱値
317 static void pile_monster_conf(player_type *caster_ptr, effect_monster_type *em_ptr, int *conf_damage)
319 if ((em_ptr->do_conf == 0) || (em_ptr->r_ptr->flags3 & RF3_NO_CONF) || (em_ptr->r_ptr->flagsr & RFR_EFF_RES_CHAO_MASK))
323 em_ptr->obvious = TRUE;
325 if (monster_confused_remaining(em_ptr->m_ptr)) {
326 em_ptr->note = _("はさらに混乱したようだ。", " looks more confused.");
327 *conf_damage = monster_confused_remaining(em_ptr->m_ptr) + (em_ptr->do_conf / 2);
329 em_ptr->note = _("は混乱したようだ。", " looks confused.");
330 *conf_damage = em_ptr->do_conf;
333 (void)set_monster_confused(caster_ptr, em_ptr->g_ptr->m_idx, *conf_damage);
334 em_ptr->get_angry = TRUE;
339 * @param em_ptr モンスター効果構造体への参照ポインタ
342 static void process_monster_weakening(effect_monster_type *em_ptr)
344 if (em_ptr->do_time == 0)
348 em_ptr->obvious = TRUE;
350 if (em_ptr->do_time >= em_ptr->m_ptr->maxhp)
351 em_ptr->do_time = em_ptr->m_ptr->maxhp - 1;
353 if (em_ptr->do_time) {
354 em_ptr->note = _("は弱くなったようだ。", " seems weakened.");
355 em_ptr->m_ptr->maxhp -= em_ptr->do_time;
356 if ((em_ptr->m_ptr->hp - em_ptr->dam) > em_ptr->m_ptr->maxhp)
357 em_ptr->dam = em_ptr->m_ptr->hp - em_ptr->m_ptr->maxhp;
360 em_ptr->get_angry = TRUE;
365 * @param caster_ptr プレーヤーへの参照ポインタ
366 * @param em_ptr モンスター効果構造体への参照ポインタ
369 static void process_monster_polymorph(player_type *caster_ptr, effect_monster_type *em_ptr)
371 if (!em_ptr->do_polymorph || (randint1(90) <= em_ptr->r_ptr->level))
374 if (polymorph_monster(caster_ptr, em_ptr->y, em_ptr->x)) {
376 em_ptr->obvious = TRUE;
378 em_ptr->note = _("が変身した!", " changes!");
382 em_ptr->m_ptr = &caster_ptr->current_floor_ptr->m_list[em_ptr->g_ptr->m_idx];
383 em_ptr->r_ptr = &r_info[em_ptr->m_ptr->r_idx];
387 * @brief モンスターをテレポートさせる
388 * @param caster_ptr プレーヤーへの参照ポインタ
389 * @param em_ptr モンスター効果構造体への参照ポインタ
392 static void process_monster_teleport(player_type *caster_ptr, effect_monster_type *em_ptr)
394 if (em_ptr->do_dist == 0)
398 em_ptr->obvious = TRUE;
400 em_ptr->note = _("が消え去った!", " disappears!");
403 chg_virtue(caster_ptr, V_VALOUR, -1);
405 teleport_away(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->do_dist, (!em_ptr->who ? TELEPORT_DEC_VALOUR : 0L) | TELEPORT_PASSIVE);
407 em_ptr->y = em_ptr->m_ptr->fy;
408 em_ptr->x = em_ptr->m_ptr->fx;
409 em_ptr->g_ptr = &caster_ptr->current_floor_ptr->grid_array[em_ptr->y][em_ptr->x];
413 * @brief モンスターの異常状態を処理する
414 * @param caster_ptr プレーヤーへの参照ポインタ
415 * @param em_ptr モンスター効果構造体への参照ポインタ
416 * @parama tmp_damage 朦朧/混乱値
419 static void process_monster_bad_status(player_type *caster_ptr, effect_monster_type *em_ptr, int *tmp_damage)
421 pile_monster_stun(caster_ptr, em_ptr, tmp_damage);
422 pile_monster_conf(caster_ptr, em_ptr, tmp_damage);
423 process_monster_weakening(em_ptr);
424 process_monster_polymorph(caster_ptr, em_ptr);
425 process_monster_teleport(caster_ptr, em_ptr);
426 if (em_ptr->do_fear == 0)
429 (void)set_monster_monfear(caster_ptr, em_ptr->g_ptr->m_idx, monster_fear_remaining(em_ptr->m_ptr) + em_ptr->do_fear);
430 em_ptr->get_angry = TRUE;
434 * @brief モンスターへのダメージに応じたメッセージを表示させ、異常状態を与える
435 * @param caster_ptr プレーヤーへの参照ポインタ
436 * @param em_ptr モンスター効果構造体への参照ポインタ
439 static void process_monster_bad_stat_damage(player_type *caster_ptr, effect_monster_type *em_ptr)
441 int tmp_damage = em_ptr->dam;
442 em_ptr->dam = mon_damage_mod(caster_ptr, em_ptr->m_ptr, em_ptr->dam, (bool)(em_ptr->effect_type == GF_PSY_SPEAR));
443 if ((tmp_damage > 0) && (em_ptr->dam == 0))
444 em_ptr->note = _("はダメージを受けていない。", " is unharmed.");
446 if (em_ptr->dam > em_ptr->m_ptr->hp)
447 em_ptr->note = em_ptr->note_dies;
449 process_monster_bad_status(caster_ptr, em_ptr, &tmp_damage);
453 * todo 関数名が微妙、もっと適切な関数名が欲しい
454 * @brief モンスターへの影響全般を処理する
455 * @param caster_ptr プレーヤーへの参照ポインタ
456 * @param em_ptr モンスター効果構造体への参照ポインタ
459 static void process_spell(player_type *caster_ptr, effect_monster_type *em_ptr)
461 process_spell_result(caster_ptr, em_ptr);
462 process_monster_bad_stat_damage(caster_ptr, em_ptr);
463 process_monster_last_moment(caster_ptr, em_ptr);
464 if ((em_ptr->effect_type == GF_BLOOD_CURSE) && one_in_(4))
465 blood_curse_to_enemy(caster_ptr, em_ptr->who);
469 * @brief モンスター闘技場にいる場合の画面更新処理
470 * @param caster_ptr プレーヤーへの参照ポインタ
471 * @param em_ptr モンスター効果構造体への参照ポインタ
474 static void update_phase_out_stat(player_type *caster_ptr, effect_monster_type *em_ptr)
476 if (!caster_ptr->phase_out)
479 caster_ptr->health_who = em_ptr->g_ptr->m_idx;
480 caster_ptr->redraw |= (PR_HEALTH);
481 handle_stuff(caster_ptr);
485 * @brief 魔法効果がペットに及んだ時の処理
486 * @param caster_ptr プレーヤーへの参照ポインタ
487 * @param em_ptr モンスター効果構造体への参照ポインタ
490 static void postprocess_spell_pet(player_type *caster_ptr, effect_monster_type *em_ptr)
492 if ((em_ptr->dam <= 0) || is_pet(em_ptr->m_ptr) || is_friendly(em_ptr->m_ptr))
495 if (em_ptr->who == 0) {
496 if (!(em_ptr->flag & PROJECT_NO_HANGEKI))
497 set_target(em_ptr->m_ptr, monster_target_y, monster_target_x);
502 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))
503 set_target(em_ptr->m_ptr, em_ptr->m_caster_ptr->fy, em_ptr->m_caster_ptr->fx);
507 * @brief 魔法効果が騎乗モンスターに及んだ時の処理
508 * @param caster_ptr プレーヤーへの参照ポインタ
509 * @param em_ptr モンスター効果構造体への参照ポインタ
512 static void postprocess_spell_riding(player_type *caster_ptr, effect_monster_type *em_ptr)
514 if (!caster_ptr->riding || (caster_ptr->riding != em_ptr->g_ptr->m_idx) || (em_ptr->dam <= 0))
517 if (em_ptr->m_ptr->hp > (em_ptr->m_ptr->maxhp / 3))
518 em_ptr->dam = (em_ptr->dam + 1) / 2;
520 rakubadam_m = (em_ptr->dam > 200) ? 200 : em_ptr->dam;
525 * @param caster_ptr プレーヤーへの参照ポインタ
526 * @param em_ptr モンスター効果構造体への参照ポインタ
528 * @details 写真のフラッシュは弱閃光属性
530 static void postprocess_spell_photo(player_type *caster_ptr, effect_monster_type *em_ptr)
532 if (em_ptr->photo == 0)
538 object_prep(caster_ptr, q_ptr, lookup_kind(TV_STATUE, SV_PHOTO));
539 q_ptr->pval = em_ptr->photo;
540 q_ptr->ident |= (IDENT_FULL_KNOWN);
541 (void)drop_near(caster_ptr, q_ptr, -1, caster_ptr->y, caster_ptr->x);
545 * @brief モンスター効果の後処理 (ペット関係、記念撮影、グローバル変数更新)
546 * @param caster_ptr プレーヤーへの参照ポインタ
547 * @param em_ptr モンスター効果構造体への参照ポインタ
550 static void postprocess_spell(player_type *caster_ptr, effect_monster_type *em_ptr)
552 postprocess_spell_pet(caster_ptr, em_ptr);
553 postprocess_spell_riding(caster_ptr, em_ptr);
554 postprocess_spell_photo(caster_ptr, em_ptr);
556 project_m_x = em_ptr->x;
557 project_m_y = em_ptr->y;
561 * @brief 汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.
562 * @param caster_ptr プレーヤーへの参照ポインタ
563 * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
564 * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
565 * @param y 目標y座標 / Target y location (or location to travel "towards")
566 * @param x 目標x座標 / Target x location (or location to travel "towards")
567 * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
568 * @param effect_type 効果属性 / Type of damage to apply to monsters (and objects)
570 * @param see_s_msg TRUEならばメッセージを表示する
571 * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
574 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)
576 effect_monster_type tmp_effect;
577 effect_monster_type *em_ptr = initialize_effect_monster(caster_ptr, &tmp_effect, who, r, y, x, dam, effect_type, flag, see_s_msg);
578 if (!is_never_effect(caster_ptr, em_ptr))
581 decide_spell_result_description(caster_ptr, em_ptr);
582 process_result result = process_monster_perfect_resistance(caster_ptr, em_ptr);
583 if (result != PROCESS_CONTINUE)
589 process_spell(caster_ptr, em_ptr);
590 update_phase_out_stat(caster_ptr, em_ptr);
591 if (em_ptr->m_ptr->r_idx)
592 update_monster(caster_ptr, em_ptr->g_ptr->m_idx, FALSE);
594 lite_spot(caster_ptr, em_ptr->y, em_ptr->x);
595 if ((caster_ptr->monster_race_idx == em_ptr->m_ptr->r_idx) && (em_ptr->seen || !em_ptr->m_ptr->r_idx))
596 caster_ptr->window |= (PW_MONSTER);
598 postprocess_spell(caster_ptr, em_ptr);
599 return em_ptr->obvious;