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