OSDN Git Service

[Refactor] #39963 Reshaped effect_monster_disp_*()
[hengband/hengband.git] / src / effect / effect-monster-switcher.c
1 /*!
2  * @brief 魔法種別による各種処理切り替え
3  * @date 2020/04/29
4  * @author Hourier
5  */
6
7 #include "angband.h"
8 #include "effect-monster-util.h"
9 #include "effect/effect-monster-switcher.h"
10 #include "player-damage.h"
11 #include "avatar.h"
12 #include "monster-spell.h"
13 #include "quest.h"
14 #include "monster-status.h"
15 #include "effect/spells-effect-util.h"
16 #include "player-effects.h"
17 #include "monsterrace-hook.h"
18 #include "combat/melee.h"
19 #include "cmd/cmd-pet.h" // 暫定、後で消すかも.
20 #include "spell/spells-type.h"
21 #include "effect/effect-monster-resist-hurt.h"
22 #include "effect/effect-monster-psi.h"
23 #include "effect/effect-monster-domination.h"
24 #include "effect/effect-monster-oldies.h"
25 #include "effect/effect-monster-charm.h"
26 #include "effect/effect-monster-lite-dark.h"
27
28 gf_switch_result effect_monster_hypodynamia(player_type *caster_ptr, effect_monster_type *em_ptr)
29 {
30         if (em_ptr->seen) em_ptr->obvious = TRUE;
31         if (monster_living(em_ptr->m_ptr->r_idx))
32         {
33                 em_ptr->do_time = (em_ptr->dam + 7) / 8;
34                 return GF_SWITCH_CONTINUE;
35         }
36
37         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
38         {
39                 if (em_ptr->r_ptr->flags3 & RF3_DEMON) em_ptr->r_ptr->r_flags3 |= (RF3_DEMON);
40                 if (em_ptr->r_ptr->flags3 & RF3_UNDEAD) em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
41                 if (em_ptr->r_ptr->flags3 & RF3_NONLIVING) em_ptr->r_ptr->r_flags3 |= (RF3_NONLIVING);
42         }
43
44         em_ptr->note = _("には効果がなかった。", " is unaffected.");
45         em_ptr->obvious = FALSE;
46         em_ptr->dam = 0;
47         return GF_SWITCH_CONTINUE;
48 }
49
50
51 // todo リファクタリング前のコード時点で、単に耐性があるだけでもダメージ0だった.
52 gf_switch_result effect_monster_death_ray(player_type *caster_ptr, effect_monster_type *em_ptr)
53 {
54         if (em_ptr->seen) em_ptr->obvious = TRUE;
55
56         if (!monster_living(em_ptr->m_ptr->r_idx))
57         {
58                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
59                 {
60                         if (em_ptr->r_ptr->flags3 & RF3_DEMON) em_ptr->r_ptr->r_flags3 |= (RF3_DEMON);
61                         if (em_ptr->r_ptr->flags3 & RF3_UNDEAD) em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
62                         if (em_ptr->r_ptr->flags3 & RF3_NONLIVING) em_ptr->r_ptr->r_flags3 |= (RF3_NONLIVING);
63                 }
64
65                 em_ptr->note = _("には完全な耐性がある!", " is immune.");
66                 em_ptr->obvious = FALSE;
67                 em_ptr->dam = 0;
68                 return GF_SWITCH_CONTINUE;
69         }
70
71         if (((em_ptr->r_ptr->flags1 & RF1_UNIQUE) &&
72                 (randint1(888) != 666)) ||
73                 (((em_ptr->r_ptr->level + randint1(20)) > randint1((em_ptr->caster_lev / 2) + randint1(10))) &&
74                         randint1(100) != 66))
75         {
76                 em_ptr->note = _("には耐性がある!", " resists!");
77                 em_ptr->obvious = FALSE;
78                 em_ptr->dam = 0;
79         }
80
81         return GF_SWITCH_CONTINUE;
82 }
83
84
85 gf_switch_result effect_monster_stasis(effect_monster_type *em_ptr, bool to_evil)
86 {
87         if (em_ptr->seen) em_ptr->obvious = TRUE;
88
89         int stasis_damage = (em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10);
90         bool has_resistance = (em_ptr->r_ptr->flags1 & RF1_UNIQUE) != 0;
91         has_resistance |= em_ptr->r_ptr->level > randint1(stasis_damage) + 10;
92         if (to_evil) has_resistance |= (em_ptr->r_ptr->flags3 & RF3_EVIL) == 0;
93
94         if (has_resistance)
95         {
96                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
97                 em_ptr->obvious = FALSE;
98         }
99         else
100         {
101                 em_ptr->note = _("は動けなくなった!", " is suspended!");
102                 em_ptr->do_sleep = 500;
103         }
104
105         em_ptr->dam = 0;
106         return GF_SWITCH_CONTINUE;
107 }
108
109
110 gf_switch_result effect_monster_stun(effect_monster_type *em_ptr)
111 {
112         if (em_ptr->seen) em_ptr->obvious = TRUE;
113
114         em_ptr->do_stun = damroll((em_ptr->caster_lev / 20) + 3, (em_ptr->dam)) + 1;
115         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
116                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
117         {
118                 em_ptr->do_stun = 0;
119                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
120                 em_ptr->obvious = FALSE;
121         }
122
123         em_ptr->dam = 0;
124         return GF_SWITCH_CONTINUE;
125 }
126
127
128 gf_switch_result effect_monster_kill_wall(player_type *caster_ptr, effect_monster_type *em_ptr)
129 {
130         if ((em_ptr->r_ptr->flags3 & (RF3_HURT_ROCK)) == 0)
131         {
132                 em_ptr->dam = 0;
133                 return GF_SWITCH_CONTINUE;
134         }
135
136         if (em_ptr->seen) em_ptr->obvious = TRUE;
137
138         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_HURT_ROCK);
139
140         em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
141         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
142         return GF_SWITCH_CONTINUE;
143 }
144
145
146 static bool effect_monster_away_resist(player_type *caster_ptr, effect_monster_type *em_ptr)
147 {
148         if ((em_ptr->r_ptr->flagsr & RFR_RES_TELE) == 0) return FALSE;
149
150         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) || (em_ptr->r_ptr->flagsr & RFR_RES_ALL))
151         {
152                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flagsr |= RFR_RES_TELE;
153                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
154                 return TRUE;
155         }
156         
157         if (em_ptr->r_ptr->level > randint1(100))
158         {
159                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flagsr |= RFR_RES_TELE;
160                 em_ptr->note = _("には耐性がある!", " resists!");
161                 return TRUE;
162         }
163
164         return FALSE;
165 }
166
167
168 gf_switch_result effect_monster_away_undead(player_type *caster_ptr, effect_monster_type *em_ptr)
169 {
170         if ((em_ptr->r_ptr->flags3 & (RF3_UNDEAD)) == 0)
171         {
172                 em_ptr->skipped = TRUE;
173                 em_ptr->dam = 0;
174                 return GF_SWITCH_CONTINUE;
175         }
176
177         bool resists_tele = effect_monster_away_resist(caster_ptr, em_ptr);
178         if (!resists_tele)
179         {
180                 if (em_ptr->seen) em_ptr->obvious = TRUE;
181                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
182                         em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
183
184                 em_ptr->do_dist = em_ptr->dam;
185         }
186
187         em_ptr->dam = 0;
188         return GF_SWITCH_CONTINUE;
189 }
190
191
192 gf_switch_result effect_monster_away_evil(player_type *caster_ptr, effect_monster_type *em_ptr)
193 {
194         if ((em_ptr->r_ptr->flags3 & (RF3_EVIL)) == 0)
195         {
196                 em_ptr->skipped = TRUE;
197                 em_ptr->dam = 0;
198                 return GF_SWITCH_CONTINUE;
199         }
200
201         bool resists_tele = effect_monster_away_resist(caster_ptr, em_ptr);
202         if (!resists_tele)
203         {
204                 if (em_ptr->seen) em_ptr->obvious = TRUE;
205                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
206                         em_ptr->r_ptr->r_flags3 |= (RF3_EVIL);
207
208                 em_ptr->do_dist = em_ptr->dam;
209         }
210
211         em_ptr->dam = 0;
212         return GF_SWITCH_CONTINUE;
213 }
214
215
216 gf_switch_result effect_monster_away_all(player_type *caster_ptr, effect_monster_type *em_ptr)
217 {
218         bool resists_tele = effect_monster_away_resist(caster_ptr, em_ptr);
219         if (!resists_tele)
220         {
221                 if (em_ptr->seen) em_ptr->obvious = TRUE;
222
223                 em_ptr->do_dist = em_ptr->dam;
224         }
225
226         em_ptr->dam = 0;
227         return GF_SWITCH_CONTINUE;
228 }
229
230
231 gf_switch_result effect_monster_turn_undead(player_type *caster_ptr, effect_monster_type *em_ptr)
232 {
233         if ((em_ptr->r_ptr->flags3 & (RF3_UNDEAD)) == 0)
234         {
235                 em_ptr->skipped = TRUE;
236                 em_ptr->dam = 0;
237                 return GF_SWITCH_CONTINUE;
238         }
239
240         if (em_ptr->seen) em_ptr->obvious = TRUE;
241
242         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
243
244         em_ptr->do_fear = damroll(3, (em_ptr->dam / 2)) + 1;
245         if (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10)
246         {
247                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
248                 em_ptr->obvious = FALSE;
249                 em_ptr->do_fear = 0;
250         }
251
252         em_ptr->dam = 0;
253         return GF_SWITCH_CONTINUE;
254 }
255
256
257 gf_switch_result effect_monster_turn_evil(player_type *caster_ptr, effect_monster_type *em_ptr)
258 {
259         if ((em_ptr->r_ptr->flags3 & (RF3_EVIL)) == 0)
260         {
261                 em_ptr->skipped = TRUE;
262                 em_ptr->dam = 0;
263                 return GF_SWITCH_CONTINUE;
264         }
265
266         if (em_ptr->seen) em_ptr->obvious = TRUE;
267
268         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_EVIL);
269
270         em_ptr->do_fear = damroll(3, (em_ptr->dam / 2)) + 1;
271         if (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10)
272         {
273                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
274                 em_ptr->obvious = FALSE;
275                 em_ptr->do_fear = 0;
276         }
277
278         em_ptr->dam = 0;
279         return GF_SWITCH_CONTINUE;
280 }
281
282
283 gf_switch_result effect_monster_turn_all(effect_monster_type *em_ptr)
284 {
285         if (em_ptr->seen) em_ptr->obvious = TRUE;
286
287         em_ptr->do_fear = damroll(3, (em_ptr->dam / 2)) + 1;
288         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
289                 (em_ptr->r_ptr->flags3 & (RF3_NO_FEAR)) ||
290                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
291         {
292                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
293                 em_ptr->obvious = FALSE;
294                 em_ptr->do_fear = 0;
295         }
296
297         em_ptr->dam = 0;
298         return GF_SWITCH_CONTINUE;
299 }
300
301
302 gf_switch_result effect_monster_disp_undead(player_type *caster_ptr, effect_monster_type *em_ptr)
303 {
304         if ((em_ptr->r_ptr->flags3 & (RF3_UNDEAD)) == 0)
305         {
306                 em_ptr->skipped = TRUE;
307                 em_ptr->dam = 0;
308                 return GF_SWITCH_CONTINUE;
309         }
310
311         if (em_ptr->seen) em_ptr->obvious = TRUE;
312
313         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
314                 em_ptr->r_ptr->r_flags3 |= (RF3_UNDEAD);
315
316         em_ptr->note = _("は身震いした。", " shudders.");
317         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
318         return GF_SWITCH_CONTINUE;
319 }
320
321
322 gf_switch_result effect_monster_disp_evil(player_type *caster_ptr, effect_monster_type *em_ptr)
323 {
324         if ((em_ptr->r_ptr->flags3 & (RF3_EVIL)) == 0)
325         {
326                 em_ptr->skipped = TRUE;
327                 em_ptr->dam = 0;
328                 return GF_SWITCH_CONTINUE;
329         }
330
331         if (em_ptr->seen) em_ptr->obvious = TRUE;
332
333         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_EVIL);
334
335         em_ptr->note = _("は身震いした。", " shudders.");
336         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
337         return GF_SWITCH_CONTINUE;
338 }
339
340
341 gf_switch_result effect_monster_disp_good(player_type *caster_ptr, effect_monster_type *em_ptr)
342 {
343         if ((em_ptr->r_ptr->flags3 & (RF3_GOOD)) == 0)
344         {
345                 em_ptr->skipped = TRUE;
346                 em_ptr->dam = 0;
347                 return GF_SWITCH_CONTINUE;
348         }
349
350         if (em_ptr->seen) em_ptr->obvious = TRUE;
351
352         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_GOOD);
353
354         em_ptr->note = _("は身震いした。", " shudders.");
355         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
356         return GF_SWITCH_CONTINUE;
357 }
358
359
360 gf_switch_result effect_monster_disp_living(effect_monster_type *em_ptr)
361 {
362         if (!monster_living(em_ptr->m_ptr->r_idx))
363         {
364                 em_ptr->skipped = TRUE;
365                 em_ptr->dam = 0;
366                 return GF_SWITCH_CONTINUE;
367         }
368
369         if (em_ptr->seen) em_ptr->obvious = TRUE;
370
371         em_ptr->note = _("は身震いした。", " shudders.");
372         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
373         return GF_SWITCH_CONTINUE;
374 }
375
376
377 gf_switch_result effect_monster_disp_demon(player_type *caster_ptr, effect_monster_type *em_ptr)
378 {
379         if ((em_ptr->r_ptr->flags3 & (RF3_DEMON)) == 0)
380         {
381                 em_ptr->skipped = TRUE;
382                 em_ptr->dam = 0;
383                 return GF_SWITCH_CONTINUE;
384         }
385
386         if (em_ptr->seen) em_ptr->obvious = TRUE;
387
388         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_DEMON);
389
390         em_ptr->note = _("は身震いした。", " shudders.");
391         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
392         return GF_SWITCH_CONTINUE;
393 }
394
395
396 gf_switch_result effect_monster_disp_all(effect_monster_type *em_ptr)
397 {
398         if (em_ptr->seen) em_ptr->obvious = TRUE;
399
400         em_ptr->note = _("は身震いした。", " shudders.");
401         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
402 }
403
404
405 /*!
406  * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
407  * @param em_ptr モンスター効果構造体への参照ポインタ
408  * @return ここのスイッチングで終るならTRUEかFALSE、後続処理を実行するならCONTINUE
409  */
410 gf_switch_result switch_effects_monster(player_type *caster_ptr, effect_monster_type *em_ptr)
411 {
412         floor_type *floor_ptr = caster_ptr->current_floor_ptr;
413         switch (em_ptr->effect_type)
414         {
415         case GF_PSY_SPEAR:
416         case GF_MISSILE:
417         case GF_ARROW:
418         case GF_MANA:
419         case GF_METEOR:
420         case GF_BLOOD_CURSE:
421         case GF_SEEKER:
422         case GF_SUPER_RAY:
423                 return effect_monster_void(em_ptr);
424         case GF_ACID:
425                 return effect_monster_acid(caster_ptr, em_ptr);
426         case GF_ELEC:
427                 return effect_monster_elec(caster_ptr, em_ptr);
428         case GF_FIRE:
429                 return effect_monster_fire(caster_ptr, em_ptr);
430         case GF_COLD:
431                 return effect_monster_cold(caster_ptr, em_ptr);
432         case GF_POIS:
433                 return effect_monster_pois(caster_ptr, em_ptr);
434         case GF_NUKE:
435                 return effect_monster_nuke(caster_ptr, em_ptr);
436         case GF_HELL_FIRE:
437                 return effect_monster_hell_fire(caster_ptr, em_ptr);
438         case GF_HOLY_FIRE:
439                 return effect_monster_holy_fire(caster_ptr, em_ptr);
440         case GF_PLASMA:
441                 return effect_monster_plasma(caster_ptr, em_ptr);
442         case GF_NETHER:
443                 return effect_monster_nether(caster_ptr, em_ptr);
444         case GF_WATER:
445                 return effect_monster_water(caster_ptr, em_ptr);
446         case GF_CHAOS:
447                 return effect_monster_chaos(caster_ptr, em_ptr);
448         case GF_SHARDS:
449                 return effect_monster_shards(caster_ptr, em_ptr);
450         case GF_ROCKET:
451                 return effect_monster_rocket(caster_ptr, em_ptr);
452         case GF_SOUND:
453                 return effect_monster_sound(caster_ptr, em_ptr);
454         case GF_CONFUSION:
455                 return effect_monster_confusion(caster_ptr, em_ptr);
456         case GF_DISENCHANT:
457                 return effect_monster_disenchant(caster_ptr, em_ptr);
458         case GF_NEXUS:
459                 return effect_monster_nexus(caster_ptr, em_ptr);
460         case GF_FORCE:
461                 return effect_monster_force(caster_ptr, em_ptr);
462         case GF_INERTIAL:
463                 return effect_monster_inertial(caster_ptr, em_ptr);
464         case GF_TIME:
465                 return effect_monster_time(caster_ptr, em_ptr);
466         case GF_GRAVITY:
467                 return effect_monster_gravity(caster_ptr, em_ptr);
468         case GF_DISINTEGRATE:
469                 return effect_monster_disintegration(caster_ptr, em_ptr);
470         case GF_PSI:
471                 return effect_monster_psi(caster_ptr, em_ptr);
472         case GF_PSI_DRAIN:
473                 return effect_monster_psi_drain(caster_ptr, em_ptr);
474         case GF_TELEKINESIS:
475                 return effect_monster_telekinesis(caster_ptr, em_ptr);
476         case GF_DOMINATION:
477                 return effect_monster_domination(caster_ptr, em_ptr);
478         case GF_ICE:
479                 return effect_monster_icee_bolt(caster_ptr, em_ptr);
480         case GF_HYPODYNAMIA:
481                 return effect_monster_hypodynamia(caster_ptr, em_ptr);
482         case GF_DEATH_RAY:
483                 return effect_monster_death_ray(caster_ptr, em_ptr);
484         case GF_OLD_POLY:
485                 return effect_monster_old_poly(em_ptr);
486         case GF_OLD_CLONE:
487                 return effect_monster_old_clone(caster_ptr, em_ptr);
488         case GF_STAR_HEAL:
489                 if (effect_monster_old_clone(caster_ptr, em_ptr) == GF_SWITCH_TRUE)
490                         return GF_SWITCH_CONTINUE;
491         /* Fall through */
492         case GF_OLD_HEAL:
493                 return effect_monster_old_heal(caster_ptr, em_ptr);
494         case GF_OLD_SPEED:
495                 return effect_monster_old_speed(caster_ptr, em_ptr);
496         case GF_OLD_SLOW:
497                 return effect_monster_old_slow(caster_ptr, em_ptr);
498         case GF_OLD_SLEEP:
499                 return effect_monster_old_sleep(caster_ptr, em_ptr);
500         case GF_STASIS_EVIL:
501                 return effect_monster_stasis(em_ptr, TRUE);
502         case GF_STASIS:
503                 return effect_monster_stasis(em_ptr, FALSE);
504         case GF_CHARM:
505                 return effect_monster_charm(caster_ptr, em_ptr);
506         case GF_CONTROL_UNDEAD:
507                 return effect_monster_control_undead(caster_ptr, em_ptr);
508         case GF_CONTROL_DEMON:
509                 return effect_monster_control_demon(caster_ptr, em_ptr);
510         case GF_CONTROL_ANIMAL:
511                 return effect_monster_control_animal(caster_ptr, em_ptr);
512         case GF_CHARM_LIVING:
513                 return effect_monster_charm_living(caster_ptr, em_ptr);
514         case GF_OLD_CONF:
515                 return effect_monster_old_conf(caster_ptr, em_ptr);
516         case GF_STUN:
517                 return effect_monster_stun(em_ptr);
518         case GF_LITE_WEAK:
519                 return effect_monster_lite_weak(caster_ptr, em_ptr);
520         case GF_LITE:
521                 return effect_monster_lite(caster_ptr, em_ptr);
522         case GF_DARK:
523                 return effect_monster_dark(caster_ptr, em_ptr);
524         case GF_KILL_WALL:
525                 return effect_monster_kill_wall(caster_ptr, em_ptr);
526         case GF_AWAY_UNDEAD:
527                 return effect_monster_away_undead(caster_ptr, em_ptr);
528         case GF_AWAY_EVIL:
529                 return effect_monster_away_evil(caster_ptr, em_ptr);
530         case GF_AWAY_ALL:
531                 return effect_monster_away_all(caster_ptr, em_ptr);
532         case GF_TURN_UNDEAD:
533                 return effect_monster_turn_undead(caster_ptr, em_ptr);
534         case GF_TURN_EVIL:
535                 return effect_monster_turn_evil(caster_ptr, em_ptr);
536         case GF_TURN_ALL:
537                 return effect_monster_turn_all(em_ptr);
538         case GF_DISP_UNDEAD:
539                 return effect_monster_disp_undead(caster_ptr, em_ptr);
540         case GF_DISP_EVIL:
541                 return effect_monster_disp_evil(caster_ptr, em_ptr);
542         case GF_DISP_GOOD:
543                 return effect_monster_disp_good(caster_ptr, em_ptr);
544         case GF_DISP_LIVING:
545                 return effect_monster_disp_living(em_ptr);
546         case GF_DISP_DEMON:
547                 return effect_monster_disp_demon(caster_ptr, em_ptr);
548         case GF_DISP_ALL:
549                 return effect_monster_disp_all(em_ptr);
550         case GF_DRAIN_MANA:
551         {
552                 if (em_ptr->seen) em_ptr->obvious = TRUE;
553                 if ((em_ptr->r_ptr->flags4 & ~(RF4_NOMAGIC_MASK)) || (em_ptr->r_ptr->a_ability_flags1 & ~(RF5_NOMAGIC_MASK)) || (em_ptr->r_ptr->a_ability_flags2 & ~(RF6_NOMAGIC_MASK)))
554                 {
555                         if (em_ptr->who > 0)
556                         {
557                                 if (em_ptr->m_caster_ptr->hp < em_ptr->m_caster_ptr->maxhp)
558                                 {
559                                         em_ptr->m_caster_ptr->hp += em_ptr->dam;
560                                         if (em_ptr->m_caster_ptr->hp > em_ptr->m_caster_ptr->maxhp) em_ptr->m_caster_ptr->hp = em_ptr->m_caster_ptr->maxhp;
561                                         if (caster_ptr->health_who == em_ptr->who) caster_ptr->redraw |= (PR_HEALTH);
562                                         if (caster_ptr->riding == em_ptr->who) caster_ptr->redraw |= (PR_UHEALTH);
563
564                                         if (em_ptr->see_s_msg)
565                                         {
566                                                 monster_desc(caster_ptr, em_ptr->killer, em_ptr->m_caster_ptr, 0);
567                                                 msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), em_ptr->killer);
568                                         }
569                                 }
570                         }
571                         else
572                         {
573                                 msg_format(_("%sから精神エネルギーを吸いとった。", "You draw psychic energy from %s."), em_ptr->m_name);
574                                 (void)hp_player(caster_ptr, em_ptr->dam);
575                         }
576                 }
577                 else
578                 {
579                         if (em_ptr->see_s_msg) msg_format(_("%sには効果がなかった。", "%s is unaffected."), em_ptr->m_name);
580                 }
581
582                 em_ptr->dam = 0;
583                 break;
584         }
585         case GF_MIND_BLAST:
586         {
587                 if (em_ptr->seen) em_ptr->obvious = TRUE;
588                 if (!em_ptr->who) msg_format(_("%sをじっと睨んだ。", "You gaze intently at %s."), em_ptr->m_name);
589
590                 if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
591                         (em_ptr->r_ptr->flags3 & RF3_NO_CONF) ||
592                         (em_ptr->r_ptr->level > randint1((em_ptr->caster_lev - 10) < 1 ? 1 : (em_ptr->caster_lev - 10)) + 10))
593                 {
594                         if (em_ptr->r_ptr->flags3 & (RF3_NO_CONF))
595                         {
596                                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_CONF);
597                         }
598
599                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
600                         em_ptr->dam = 0;
601                 }
602                 else if (em_ptr->r_ptr->flags2 & RF2_EMPTY_MIND)
603                 {
604                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
605                         em_ptr->note = _("には完全な耐性がある!", " is immune.");
606                         em_ptr->dam = 0;
607                 }
608                 else if (em_ptr->r_ptr->flags2 & RF2_WEIRD_MIND)
609                 {
610                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_WEIRD_MIND);
611                         em_ptr->note = _("には耐性がある。", " resists.");
612                         em_ptr->dam /= 3;
613                 }
614                 else
615                 {
616                         em_ptr->note = _("は精神攻撃を食らった。", " is blasted by psionic energy.");
617                         em_ptr->note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
618
619                         if (em_ptr->who > 0) em_ptr->do_conf = randint0(4) + 4;
620                         else em_ptr->do_conf = randint0(8) + 8;
621                 }
622
623                 break;
624         }
625         case GF_BRAIN_SMASH:
626         {
627                 if (em_ptr->seen) em_ptr->obvious = TRUE;
628                 if (!em_ptr->who) msg_format(_("%sをじっと睨んだ。", "You gaze intently at %s."), em_ptr->m_name);
629
630                 if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
631                         (em_ptr->r_ptr->flags3 & RF3_NO_CONF) ||
632                         (em_ptr->r_ptr->level > randint1((em_ptr->caster_lev - 10) < 1 ? 1 : (em_ptr->caster_lev - 10)) + 10))
633                 {
634                         if (em_ptr->r_ptr->flags3 & (RF3_NO_CONF))
635                         {
636                                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_CONF);
637                         }
638
639                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
640                         em_ptr->dam = 0;
641                 }
642                 else if (em_ptr->r_ptr->flags2 & RF2_EMPTY_MIND)
643                 {
644                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
645                         em_ptr->note = _("には完全な耐性がある!", " is immune.");
646                         em_ptr->dam = 0;
647                 }
648                 else if (em_ptr->r_ptr->flags2 & RF2_WEIRD_MIND)
649                 {
650                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_WEIRD_MIND);
651                         em_ptr->note = _("には耐性がある!", " resists!");
652                         em_ptr->dam /= 3;
653                 }
654                 else
655                 {
656                         em_ptr->note = _("は精神攻撃を食らった。", " is blasted by psionic energy.");
657                         em_ptr->note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
658                         if (em_ptr->who > 0)
659                         {
660                                 em_ptr->do_conf = randint0(4) + 4;
661                                 em_ptr->do_stun = randint0(4) + 4;
662                         }
663                         else
664                         {
665                                 em_ptr->do_conf = randint0(8) + 8;
666                                 em_ptr->do_stun = randint0(8) + 8;
667                         }
668                         (void)set_monster_slow(caster_ptr, em_ptr->g_ptr->m_idx, MON_SLOW(em_ptr->m_ptr) + 10);
669                 }
670
671                 break;
672         }
673         case GF_CAUSE_1:
674         {
675                 if (em_ptr->seen) em_ptr->obvious = TRUE;
676                 if (!em_ptr->who) msg_format(_("%sを指差して呪いをかけた。", "You point at %s and curse."), em_ptr->m_name);
677                 if (randint0(100 + (em_ptr->caster_lev / 2)) < (em_ptr->r_ptr->level + 35))
678                 {
679                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
680                         em_ptr->dam = 0;
681                 }
682
683                 break;
684         }
685         case GF_CAUSE_2:
686         {
687                 if (em_ptr->seen) em_ptr->obvious = TRUE;
688                 if (!em_ptr->who) msg_format(_("%sを指差して恐ろしげに呪いをかけた。", "You point at %s and curse horribly."), em_ptr->m_name);
689
690                 if (randint0(100 + (em_ptr->caster_lev / 2)) < (em_ptr->r_ptr->level + 35))
691                 {
692                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
693                         em_ptr->dam = 0;
694                 }
695
696                 break;
697         }
698         case GF_CAUSE_3:
699         {
700                 if (em_ptr->seen) em_ptr->obvious = TRUE;
701                 if (!em_ptr->who) msg_format(_("%sを指差し、恐ろしげに呪文を唱えた!", "You point at %s, incanting terribly!"), em_ptr->m_name);
702
703                 if (randint0(100 + (em_ptr->caster_lev / 2)) < (em_ptr->r_ptr->level + 35))
704                 {
705                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
706                         em_ptr->dam = 0;
707                 }
708
709                 break;
710         }
711         case GF_CAUSE_4:
712         {
713                 if (em_ptr->seen) em_ptr->obvious = TRUE;
714                 if (!em_ptr->who)
715                         msg_format(_("%sの秘孔を突いて、「お前は既に死んでいる」と叫んだ。",
716                                 "You point at %s, screaming the word, 'DIE!'."), em_ptr->m_name);
717
718                 if ((randint0(100 + (em_ptr->caster_lev / 2)) < (em_ptr->r_ptr->level + 35)) && ((em_ptr->who <= 0) || (em_ptr->m_caster_ptr->r_idx != MON_KENSHIROU)))
719                 {
720                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
721                         em_ptr->dam = 0;
722                 }
723                 break;
724         }
725         case GF_HAND_DOOM:
726         {
727                 if (em_ptr->seen) em_ptr->obvious = TRUE;
728                 if (em_ptr->r_ptr->flags1 & RF1_UNIQUE)
729                 {
730                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
731                         em_ptr->dam = 0;
732                 }
733                 else
734                 {
735                         if ((em_ptr->who > 0) ? ((em_ptr->caster_lev + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + 10 + randint1(20))) :
736                                 (((em_ptr->caster_lev / 2) + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + randint1(200))))
737                         {
738                                 em_ptr->dam = ((40 + randint1(20)) * em_ptr->m_ptr->hp) / 100;
739
740                                 if (em_ptr->m_ptr->hp < em_ptr->dam) em_ptr->dam = em_ptr->m_ptr->hp - 1;
741                         }
742                         else
743                         {
744                                 em_ptr->note = _("は破滅の手に耐え切った!", "resists!");
745                                 em_ptr->dam = 0;
746                         }
747                 }
748
749                 break;
750         }
751         case GF_CAPTURE:
752         {
753                 int nokori_hp;
754                 if ((floor_ptr->inside_quest && (quest[floor_ptr->inside_quest].type == QUEST_TYPE_KILL_ALL) && !is_pet(em_ptr->m_ptr)) ||
755                         (em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) || (em_ptr->r_ptr->flags7 & (RF7_NAZGUL)) || (em_ptr->r_ptr->flags7 & (RF7_UNIQUE2)) || (em_ptr->r_ptr->flags1 & RF1_QUESTOR) || em_ptr->m_ptr->parent_m_idx)
756                 {
757                         msg_format(_("%sには効果がなかった。", "%s is unaffected."), em_ptr->m_name);
758                         em_ptr->skipped = TRUE;
759                         break;
760                 }
761
762                 if (is_pet(em_ptr->m_ptr)) nokori_hp = em_ptr->m_ptr->maxhp * 4L;
763                 else if ((caster_ptr->pclass == CLASS_BEASTMASTER) && monster_living(em_ptr->m_ptr->r_idx))
764                         nokori_hp = em_ptr->m_ptr->maxhp * 3 / 10;
765                 else
766                         nokori_hp = em_ptr->m_ptr->maxhp * 3 / 20;
767
768                 if (em_ptr->m_ptr->hp >= nokori_hp)
769                 {
770                         msg_format(_("もっと弱らせないと。", "You need to weaken %s more."), em_ptr->m_name);
771                         em_ptr->skipped = TRUE;
772                 }
773                 else if (em_ptr->m_ptr->hp < randint0(nokori_hp))
774                 {
775                         if (em_ptr->m_ptr->mflag2 & MFLAG2_CHAMELEON) choose_new_monster(caster_ptr, em_ptr->g_ptr->m_idx, FALSE, MON_CHAMELEON);
776                         msg_format(_("%sを捕えた!", "You capture %^s!"), em_ptr->m_name);
777                         cap_mon = em_ptr->m_ptr->r_idx;
778                         cap_mspeed = em_ptr->m_ptr->mspeed;
779                         cap_hp = em_ptr->m_ptr->hp;
780                         cap_maxhp = em_ptr->m_ptr->max_maxhp;
781                         cap_nickname = em_ptr->m_ptr->nickname;
782                         if (em_ptr->g_ptr->m_idx == caster_ptr->riding)
783                         {
784                                 if (rakuba(caster_ptr, -1, FALSE))
785                                 {
786                                         msg_format(_("地面に落とされた。", "You have fallen from %s."), em_ptr->m_name);
787                                 }
788                         }
789
790                         delete_monster_idx(caster_ptr, em_ptr->g_ptr->m_idx);
791
792                         return GF_SWITCH_TRUE;
793                 }
794                 else
795                 {
796                         msg_format(_("うまく捕まえられなかった。", "You failed to capture %s."), em_ptr->m_name);
797                         em_ptr->skipped = TRUE;
798                 }
799
800                 break;
801         }
802         case GF_ATTACK:
803         {
804                 return (gf_switch_result)py_attack(caster_ptr, em_ptr->y, em_ptr->x, em_ptr->dam);
805         }
806         case GF_ENGETSU:
807         {
808                 int effect = 0;
809                 bool done = TRUE;
810
811                 if (em_ptr->seen) em_ptr->obvious = TRUE;
812                 if (em_ptr->r_ptr->flags2 & RF2_EMPTY_MIND)
813                 {
814                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
815                         em_ptr->dam = 0;
816                         em_ptr->skipped = TRUE;
817                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
818                         break;
819                 }
820                 if (MON_CSLEEP(em_ptr->m_ptr))
821                 {
822                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
823                         em_ptr->dam = 0;
824                         em_ptr->skipped = TRUE;
825                         break;
826                 }
827
828                 if (one_in_(5)) effect = 1;
829                 else if (one_in_(4)) effect = 2;
830                 else if (one_in_(3)) effect = 3;
831                 else done = FALSE;
832
833                 if (effect == 1)
834                 {
835                         if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
836                                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
837                         {
838                                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
839                                 em_ptr->obvious = FALSE;
840                         }
841                         else
842                         {
843                                 if (set_monster_slow(caster_ptr, em_ptr->g_ptr->m_idx, MON_SLOW(em_ptr->m_ptr) + 50))
844                                 {
845                                         em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
846                                 }
847                         }
848                 }
849                 else if (effect == 2)
850                 {
851                         em_ptr->do_stun = damroll((caster_ptr->lev / 10) + 3, (em_ptr->dam)) + 1;
852                         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
853                                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
854                         {
855                                 em_ptr->do_stun = 0;
856                                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
857                                 em_ptr->obvious = FALSE;
858                         }
859                 }
860                 else if (effect == 3)
861                 {
862                         if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
863                                 (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP) ||
864                                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
865                         {
866                                 if (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP)
867                                 {
868                                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_SLEEP);
869                                 }
870
871                                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
872                                 em_ptr->obvious = FALSE;
873                         }
874                         else
875                         {
876                                 /* Go to sleep (much) later */
877                                 em_ptr->note = _("は眠り込んでしまった!", " falls asleep!");
878                                 em_ptr->do_sleep = 500;
879                         }
880                 }
881
882                 if (!done)
883                 {
884                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
885                 }
886
887                 em_ptr->dam = 0;
888                 break;
889         }
890         case GF_GENOCIDE:
891         {
892                 if (em_ptr->seen) em_ptr->obvious = TRUE;
893                 if (genocide_aux(caster_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam, !em_ptr->who, (em_ptr->r_ptr->level + 1) / 2, _("モンスター消滅", "Genocide One")))
894                 {
895                         if (em_ptr->seen_msg) msg_format(_("%sは消滅した!", "%^s disappeared!"), em_ptr->m_name);
896                         chg_virtue(caster_ptr, V_VITALITY, -1);
897                         return GF_SWITCH_TRUE;
898                 }
899
900                 em_ptr->skipped = TRUE;
901                 break;
902         }
903         case GF_PHOTO:
904         {
905                 if (!em_ptr->who)
906                         msg_format(_("%sを写真に撮った。", "You take a photograph of %s."), em_ptr->m_name);
907
908                 if (em_ptr->r_ptr->flags3 & (RF3_HURT_LITE))
909                 {
910                         if (em_ptr->seen) em_ptr->obvious = TRUE;
911
912                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_HURT_LITE);
913
914                         em_ptr->note = _("は光に身をすくめた!", " cringes from the light!");
915                         em_ptr->note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
916                 }
917                 else
918                 {
919                         em_ptr->dam = 0;
920                 }
921
922                 em_ptr->photo = em_ptr->m_ptr->r_idx;
923                 break;
924         }
925         case GF_CRUSADE:
926         {
927                 bool success = FALSE;
928                 if (em_ptr->seen) em_ptr->obvious = TRUE;
929
930                 if ((em_ptr->r_ptr->flags3 & (RF3_GOOD)) && !floor_ptr->inside_arena)
931                 {
932                         if (em_ptr->r_ptr->flags3 & (RF3_NO_CONF)) em_ptr->dam -= 50;
933                         if (em_ptr->dam < 1) em_ptr->dam = 1;
934
935                         if (is_pet(em_ptr->m_ptr))
936                         {
937                                 em_ptr->note = _("の動きが速くなった。", " starts moving faster.");
938                                 (void)set_monster_fast(caster_ptr, em_ptr->g_ptr->m_idx, MON_FAST(em_ptr->m_ptr) + 100);
939                                 success = TRUE;
940                         }
941                         else if ((em_ptr->r_ptr->flags1 & (RF1_QUESTOR)) ||
942                                 (em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
943                                 (em_ptr->m_ptr->mflag2 & MFLAG2_NOPET) ||
944                                 (caster_ptr->cursed & TRC_AGGRAVATE) ||
945                                 ((em_ptr->r_ptr->level + 10) > randint1(em_ptr->dam)))
946                         {
947                                 if (one_in_(4)) em_ptr->m_ptr->mflag2 |= MFLAG2_NOPET;
948                         }
949                         else
950                         {
951                                 em_ptr->note = _("を支配した。", " is tamed!");
952                                 set_pet(caster_ptr, em_ptr->m_ptr);
953                                 (void)set_monster_fast(caster_ptr, em_ptr->g_ptr->m_idx, MON_FAST(em_ptr->m_ptr) + 100);
954
955                                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_GOOD);
956                                 success = TRUE;
957                         }
958                 }
959
960                 if (!success)
961                 {
962                         if (!(em_ptr->r_ptr->flags3 & RF3_NO_FEAR))
963                         {
964                                 em_ptr->do_fear = randint1(90) + 10;
965                         }
966                         else if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr))
967                                 em_ptr->r_ptr->r_flags3 |= (RF3_NO_FEAR);
968                 }
969
970                 em_ptr->dam = 0;
971                 break;
972         }
973         case GF_WOUNDS:
974         {
975                 if (em_ptr->seen) em_ptr->obvious = TRUE;
976
977                 if (randint0(100 + em_ptr->dam) < (em_ptr->r_ptr->level + 50))
978                 {
979                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
980                         em_ptr->dam = 0;
981                 }
982                 break;
983         }
984         default:
985         {
986                 em_ptr->skipped = TRUE;
987                 em_ptr->dam = 0;
988                 break;
989         }
990         }
991
992         return GF_SWITCH_CONTINUE;
993 }