OSDN Git Service

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