OSDN Git Service

Merge remote-tracking branch 'remotes/origin/For2.2.2-Fix-Hourier' into For2.2.2...
[hengband/hengband.git] / src / effect / effect-monster-switcher.c
1 /*!
2  * todo どうしても「その他」に分類せざるを得ない魔法種別が残った
3  * 本ファイル内の行数はまともなレベルに落ち着いているので、一旦ここに留め置くこととする
4  * @brief 魔法種別による各種処理切り替え
5  * @date 2020/04/29
6  * @author Hourier
7  */
8
9 #include "effect/effect-monster-switcher.h"
10 #include "cmd-action/cmd-attack.h"
11 #include "effect/effect-monster-charm.h"
12 #include "effect/effect-monster-curse.h"
13 #include "effect/effect-monster-domination.h"
14 #include "effect/effect-monster-evil.h"
15 #include "effect/effect-monster-lite-dark.h"
16 #include "effect/effect-monster-oldies.h"
17 #include "effect/effect-monster-psi.h"
18 #include "effect/effect-monster-resist-hurt.h"
19 #include "effect/effect-monster-spirit.h"
20 #include "monster/monster-race-hook.h"
21 #include "monster/monster-status.h"
22 #include "player/avatar.h"
23 #include "player/player-damage.h"
24 #include "spell-kind/spells-genocide.h"
25 #include "spell/spells-type.h"
26
27 gf_switch_result effect_monster_hypodynamia(player_type *caster_ptr, effect_monster_type *em_ptr)
28 {
29         if (em_ptr->seen) em_ptr->obvious = TRUE;
30
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_kill_wall(player_type *caster_ptr, effect_monster_type *em_ptr)
86 {
87         if ((em_ptr->r_ptr->flags3 & (RF3_HURT_ROCK)) == 0)
88         {
89                 em_ptr->dam = 0;
90                 return GF_SWITCH_CONTINUE;
91         }
92
93         if (em_ptr->seen) em_ptr->obvious = TRUE;
94
95         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_HURT_ROCK);
96
97         em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
98         em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
99         return GF_SWITCH_CONTINUE;
100 }
101
102
103 gf_switch_result effect_monster_hand_doom(effect_monster_type *em_ptr)
104 {
105         if (em_ptr->seen) em_ptr->obvious = TRUE;
106
107         if (em_ptr->r_ptr->flags1 & RF1_UNIQUE)
108         {
109                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
110                 em_ptr->dam = 0;
111                 return GF_SWITCH_CONTINUE;
112         }
113
114         if ((em_ptr->who > 0) ? ((em_ptr->caster_lev + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + 10 + randint1(20))) :
115                 (((em_ptr->caster_lev / 2) + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + randint1(200))))
116         {
117                 em_ptr->dam = ((40 + randint1(20)) * em_ptr->m_ptr->hp) / 100;
118                 if (em_ptr->m_ptr->hp < em_ptr->dam)
119                         em_ptr->dam = em_ptr->m_ptr->hp - 1;
120         }
121         else
122         {
123                 em_ptr->note = _("は破滅の手に耐え切った!", "resists!");
124                 em_ptr->dam = 0;
125         }
126
127         return GF_SWITCH_CONTINUE;
128 }
129
130
131 gf_switch_result effect_monster_engetsu(player_type *caster_ptr, effect_monster_type *em_ptr)
132 {
133         int effect = 0;
134         bool done = TRUE;
135
136         if (em_ptr->seen) em_ptr->obvious = TRUE;
137         if (em_ptr->r_ptr->flags2 & RF2_EMPTY_MIND)
138         {
139                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
140                 em_ptr->dam = 0;
141                 em_ptr->skipped = TRUE;
142                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
143                 return GF_SWITCH_CONTINUE;
144         }
145
146         if (MON_CSLEEP(em_ptr->m_ptr))
147         {
148                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
149                 em_ptr->dam = 0;
150                 em_ptr->skipped = TRUE;
151                 return GF_SWITCH_CONTINUE;
152         }
153
154         if (one_in_(5)) effect = 1;
155         else if (one_in_(4)) effect = 2;
156         else if (one_in_(3)) effect = 3;
157         else done = FALSE;
158
159         if (effect == 1)
160         {
161                 if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
162                         (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
163                 {
164                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
165                         em_ptr->obvious = FALSE;
166                 }
167                 else
168                 {
169                         if (set_monster_slow(caster_ptr, em_ptr->g_ptr->m_idx, MON_SLOW(em_ptr->m_ptr) + 50))
170                         {
171                                 em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
172                         }
173                 }
174         }
175         else if (effect == 2)
176         {
177                 em_ptr->do_stun = damroll((caster_ptr->lev / 10) + 3, (em_ptr->dam)) + 1;
178                 if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
179                         (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
180                 {
181                         em_ptr->do_stun = 0;
182                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
183                         em_ptr->obvious = FALSE;
184                 }
185         }
186         else if (effect == 3)
187         {
188                 if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
189                         (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP) ||
190                         (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
191                 {
192                         if (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP)
193                         {
194                                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_SLEEP);
195                         }
196
197                         em_ptr->note = _("には効果がなかった。", " is unaffected.");
198                         em_ptr->obvious = FALSE;
199                 }
200                 else
201                 {
202                         /* Go to sleep (much) later */
203                         em_ptr->note = _("は眠り込んでしまった!", " falls asleep!");
204                         em_ptr->do_sleep = 500;
205                 }
206         }
207
208         if (!done)
209         {
210                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
211         }
212
213         em_ptr->dam = 0;
214         return GF_SWITCH_CONTINUE;
215 }
216
217
218 gf_switch_result effect_monster_genocide(player_type *caster_ptr, effect_monster_type *em_ptr)
219 {
220         if (em_ptr->seen) em_ptr->obvious = TRUE;
221         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")))
222         {
223                 if (em_ptr->seen_msg) msg_format(_("%sは消滅した!", "%^s disappeared!"), em_ptr->m_name);
224                 chg_virtue(caster_ptr, V_VITALITY, -1);
225                 return GF_SWITCH_TRUE;
226         }
227
228         em_ptr->skipped = TRUE;
229         return GF_SWITCH_CONTINUE;
230 }
231
232
233 gf_switch_result effect_monster_photo(player_type *caster_ptr, effect_monster_type *em_ptr)
234 {
235         if (!em_ptr->who)
236                 msg_format(_("%sを写真に撮った。", "You take a photograph of %s."), em_ptr->m_name);
237
238         if (em_ptr->r_ptr->flags3 & (RF3_HURT_LITE))
239         {
240                 if (em_ptr->seen) em_ptr->obvious = TRUE;
241
242                 if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_HURT_LITE);
243
244                 em_ptr->note = _("は光に身をすくめた!", " cringes from the light!");
245                 em_ptr->note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
246         }
247         else
248         {
249                 em_ptr->dam = 0;
250         }
251
252         em_ptr->photo = em_ptr->m_ptr->r_idx;
253         return GF_SWITCH_CONTINUE;
254 }
255
256
257 gf_switch_result effect_monster_wounds(effect_monster_type *em_ptr)
258 {
259         if (em_ptr->seen) em_ptr->obvious = TRUE;
260
261         if (randint0(100 + em_ptr->dam) < (em_ptr->r_ptr->level + 50))
262         {
263                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
264                 em_ptr->dam = 0;
265         }
266
267         return GF_SWITCH_CONTINUE;
268 }
269
270
271 /*!
272  * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
273  * @param em_ptr モンスター効果構造体への参照ポインタ
274  * @return ここのスイッチングで終るならTRUEかFALSE、後続処理を実行するならCONTINUE
275  */
276 gf_switch_result switch_effects_monster(player_type *caster_ptr, effect_monster_type *em_ptr)
277 {
278         switch (em_ptr->effect_type)
279         {
280         case GF_PSY_SPEAR:
281         case GF_MISSILE:
282         case GF_ARROW:
283         case GF_MANA:
284         case GF_METEOR:
285         case GF_BLOOD_CURSE:
286         case GF_SEEKER:
287         case GF_SUPER_RAY:
288                 return effect_monster_void(em_ptr);
289         case GF_ACID:
290                 return effect_monster_acid(caster_ptr, em_ptr);
291         case GF_ELEC:
292                 return effect_monster_elec(caster_ptr, em_ptr);
293         case GF_FIRE:
294                 return effect_monster_fire(caster_ptr, em_ptr);
295         case GF_COLD:
296                 return effect_monster_cold(caster_ptr, em_ptr);
297         case GF_POIS:
298                 return effect_monster_pois(caster_ptr, em_ptr);
299         case GF_NUKE:
300                 return effect_monster_nuke(caster_ptr, em_ptr);
301         case GF_HELL_FIRE:
302                 return effect_monster_hell_fire(caster_ptr, em_ptr);
303         case GF_HOLY_FIRE:
304                 return effect_monster_holy_fire(caster_ptr, em_ptr);
305         case GF_PLASMA:
306                 return effect_monster_plasma(caster_ptr, em_ptr);
307         case GF_NETHER:
308                 return effect_monster_nether(caster_ptr, em_ptr);
309         case GF_WATER:
310                 return effect_monster_water(caster_ptr, em_ptr);
311         case GF_CHAOS:
312                 return effect_monster_chaos(caster_ptr, em_ptr);
313         case GF_SHARDS:
314                 return effect_monster_shards(caster_ptr, em_ptr);
315         case GF_ROCKET:
316                 return effect_monster_rocket(caster_ptr, em_ptr);
317         case GF_SOUND:
318                 return effect_monster_sound(caster_ptr, em_ptr);
319         case GF_CONFUSION:
320                 return effect_monster_confusion(caster_ptr, em_ptr);
321         case GF_DISENCHANT:
322                 return effect_monster_disenchant(caster_ptr, em_ptr);
323         case GF_NEXUS:
324                 return effect_monster_nexus(caster_ptr, em_ptr);
325         case GF_FORCE:
326                 return effect_monster_force(caster_ptr, em_ptr);
327         case GF_INERTIAL:
328                 return effect_monster_inertial(caster_ptr, em_ptr);
329         case GF_TIME:
330                 return effect_monster_time(caster_ptr, em_ptr);
331         case GF_GRAVITY:
332                 return effect_monster_gravity(caster_ptr, em_ptr);
333         case GF_DISINTEGRATE:
334                 return effect_monster_disintegration(caster_ptr, em_ptr);
335         case GF_PSI:
336                 return effect_monster_psi(caster_ptr, em_ptr);
337         case GF_PSI_DRAIN:
338                 return effect_monster_psi_drain(caster_ptr, em_ptr);
339         case GF_TELEKINESIS:
340                 return effect_monster_telekinesis(caster_ptr, em_ptr);
341         case GF_DOMINATION:
342                 return effect_monster_domination(caster_ptr, em_ptr);
343         case GF_ICE:
344                 return effect_monster_icee_bolt(caster_ptr, em_ptr);
345         case GF_HYPODYNAMIA:
346                 return effect_monster_hypodynamia(caster_ptr, em_ptr);
347         case GF_DEATH_RAY:
348                 return effect_monster_death_ray(caster_ptr, em_ptr);
349         case GF_OLD_POLY:
350                 return effect_monster_old_poly(em_ptr);
351         case GF_OLD_CLONE:
352                 return effect_monster_old_clone(caster_ptr, em_ptr);
353         case GF_STAR_HEAL:
354                 if (effect_monster_old_clone(caster_ptr, em_ptr) == GF_SWITCH_TRUE)
355                         return GF_SWITCH_CONTINUE;
356         /* Fall through */
357         case GF_OLD_HEAL:
358                 return effect_monster_old_heal(caster_ptr, em_ptr);
359         case GF_OLD_SPEED:
360                 return effect_monster_old_speed(caster_ptr, em_ptr);
361         case GF_OLD_SLOW:
362                 return effect_monster_old_slow(caster_ptr, em_ptr);
363         case GF_OLD_SLEEP:
364                 return effect_monster_old_sleep(caster_ptr, em_ptr);
365         case GF_STASIS_EVIL:
366                 return effect_monster_stasis(em_ptr, TRUE);
367         case GF_STASIS:
368                 return effect_monster_stasis(em_ptr, FALSE);
369         case GF_CHARM:
370                 return effect_monster_charm(caster_ptr, em_ptr);
371         case GF_CONTROL_UNDEAD:
372                 return effect_monster_control_undead(caster_ptr, em_ptr);
373         case GF_CONTROL_DEMON:
374                 return effect_monster_control_demon(caster_ptr, em_ptr);
375         case GF_CONTROL_ANIMAL:
376                 return effect_monster_control_animal(caster_ptr, em_ptr);
377         case GF_CHARM_LIVING:
378                 return effect_monster_charm_living(caster_ptr, em_ptr);
379         case GF_OLD_CONF:
380                 return effect_monster_old_conf(caster_ptr, em_ptr);
381         case GF_STUN:
382                 return effect_monster_stun(em_ptr);
383         case GF_LITE_WEAK:
384                 return effect_monster_lite_weak(caster_ptr, em_ptr);
385         case GF_LITE:
386                 return effect_monster_lite(caster_ptr, em_ptr);
387         case GF_DARK:
388                 return effect_monster_dark(caster_ptr, em_ptr);
389         case GF_KILL_WALL:
390                 return effect_monster_kill_wall(caster_ptr, em_ptr);
391         case GF_AWAY_UNDEAD:
392                 return effect_monster_away_undead(caster_ptr, em_ptr);
393         case GF_AWAY_EVIL:
394                 return effect_monster_away_evil(caster_ptr, em_ptr);
395         case GF_AWAY_ALL:
396                 return effect_monster_away_all(caster_ptr, em_ptr);
397         case GF_TURN_UNDEAD:
398                 return effect_monster_turn_undead(caster_ptr, em_ptr);
399         case GF_TURN_EVIL:
400                 return effect_monster_turn_evil(caster_ptr, em_ptr);
401         case GF_TURN_ALL:
402                 return effect_monster_turn_all(em_ptr);
403         case GF_DISP_UNDEAD:
404                 return effect_monster_disp_undead(caster_ptr, em_ptr);
405         case GF_DISP_EVIL:
406                 return effect_monster_disp_evil(caster_ptr, em_ptr);
407         case GF_DISP_GOOD:
408                 return effect_monster_disp_good(caster_ptr, em_ptr);
409         case GF_DISP_LIVING:
410                 return effect_monster_disp_living(em_ptr);
411         case GF_DISP_DEMON:
412                 return effect_monster_disp_demon(caster_ptr, em_ptr);
413         case GF_DISP_ALL:
414                 return effect_monster_disp_all(em_ptr);
415         case GF_DRAIN_MANA:
416                 return effect_monster_drain_mana(caster_ptr, em_ptr);
417         case GF_MIND_BLAST:
418                 return effect_monster_mind_blast(caster_ptr, em_ptr);
419         case GF_BRAIN_SMASH:
420                 return effect_monster_brain_smash(caster_ptr, em_ptr);
421         case GF_CAUSE_1:
422                 return effect_monster_curse_1(em_ptr);
423         case GF_CAUSE_2:
424                 return effect_monster_curse_2(em_ptr);
425         case GF_CAUSE_3:
426                 return effect_monster_curse_3(em_ptr);
427         case GF_CAUSE_4:
428                 return effect_monster_curse_4(em_ptr);
429         case GF_HAND_DOOM:
430                 return effect_monster_hand_doom(em_ptr);
431         case GF_CAPTURE:
432                 return effect_monster_capture(caster_ptr, em_ptr);
433         case GF_ATTACK:
434                 return (gf_switch_result)do_cmd_attack(caster_ptr, em_ptr->y, em_ptr->x, em_ptr->dam);
435         case GF_ENGETSU:
436                 return effect_monster_engetsu(caster_ptr, em_ptr);
437         case GF_GENOCIDE:
438                 return effect_monster_genocide(caster_ptr, em_ptr);
439         case GF_PHOTO:
440                 return effect_monster_photo(caster_ptr, em_ptr);
441         case GF_CRUSADE:
442                 return effect_monster_crusade(caster_ptr, em_ptr);
443         case GF_WOUNDS:
444                 return effect_monster_wounds(em_ptr);
445         default:
446         {
447                 em_ptr->skipped = TRUE;
448                 em_ptr->dam = 0;
449                 return GF_SWITCH_CONTINUE;
450         }
451         }
452 }