OSDN Git Service

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