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