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