OSDN Git Service

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