OSDN Git Service

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