OSDN Git Service

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