OSDN Git Service

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