OSDN Git Service

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